Oracle® SOA Suite Developer's Guide 10g (10.1.3.1.0) Part Number B28764-01 |
|
|
View PDF |
Fault handling allows a BPEL process to handle error messages or other exceptions returned by outside web services, and to generate error messages in response to business or runtime faults. The following kinds of faults can occur:
Business faults: These application-specific faults are generated when an invoke activity receives a fault as a response or when an application executes a throw activity. Business faults are the result of a problem with the information, for example when the ID number of a current employee is not found in the employee database.
Runtime faults: These faults are generated if a BPEL process tries to use a value incorrectly, or if there is a logic error, such as an endless loop. Runtime faults are the result of problems within the BPEL process or the web services themselves, such as when data cannot be copied properly because the variable name is incorrect.
Figure 7-23 shows how fault handlers are typically incorporated within the scope activity that includes the invoke activity to a web service from which you want to handle unexpected information.
In the SOA Order Booking application, the OrderBookingFault catchAll branch is triggered if the credit validation process fails and the order is not approved. The catchAll then sets the order status to cancelled. The OrderBookingFault catchAll is shown in Figure 7-24.
Figure 7-24 Fault Handling with a CatchAll Branch in SOAOrderBooking.bpel
Within a fault handling scope, you use one or more catch branches to catch and handle faults. Within a BPEL process, use a throw activity to generate a fault.
Use a scope with a catch or catchAll branch to intercept a specific type of fault in which the data is not as expected. To catch any faults that are not already handled by name-specific catch branches, use the catchAll branch.
To handle faults with a catch or catchAll branch
Open the scope where you want to add a catch or catchAll branch.
Click the Add Catch Branch (or Add CatchAll Branch) icon.
Expand the branch you just created.
Drag and drop an Assign activity into the branch and double-click the Assign icon.
Use the Assign dialog to copy variables and expressions, as shown in Figure 7-25.
Figure 7-25 Assign Activity as Part of a Fault Handler
Click OK to close all windows.
Save the file.
To generate a fault from within a BPEL process, use a throw activity. When you add a throw activity to your BPEL process, it automatically includes a copy rule that copies the fault name and type into the output payload. The fault thrown by a throw activity is internal to BPEL. You cannot use a throw activity on an asynchronous process to communicate with a client. The throw activity has three elements: its name
, faultName
, and faultVariable
. A BPEL process can send a fault to another application to indicate a problem, as opposed to throwing an internal fault. In a synchronous operation, the reply activity can return the fault. In an asynchronous operation, the invoke activity performs this function.
To handle faults with a throw activity:
In the BPEL process where you want to generate an error or exception message, drag and drop a throw activity.
Double-click the Throw_1 icon.
Use the Throw dialog to enter values, as shown in Figure 7-26.
Click OK.
Save the file.
The faultHandlers
tag contains the fault handling code. Within the fault handler is a catch activity, which defines the fault name and variable, and the copy instruction that sets the creditRating
variable to -1000
. If a fault is not handled, it creates a faulted state that migrates up through the application and can throw the entire process into a faulted state.
Example 7-10 shows the source code for handling a fault using a catch branch in the SOA Order Booking application.
Example 7-10 Source Code for Fault Handling with a Catch Branch
<faultHandlers> <catch faultName="client:OrderBookingFault" faultVariable="OrderBookingFault"> <sequence name="Sequence_12"> <scope name="SetOrderStatus"> <variables> <variable name="orderStatusRequest" messageType="ns2:OrdersCollection_msg"/> </variables> <sequence name="Sequence_13"> <assign name="AssignOrderStatus"> <copy> <from variable="inputVariable" part="payload" query="/client:SOAOrderBookingProcessRequest/ns4:PurchaseOrder/ns4:ID"/> <to variable="orderStatusRequest" part="OrdersCollection" query="/ns9:OrdersCollection/ns9:Orders/ns9:ordid"/> </copy> <copy> <from expression="string('canceled')"/> <to variable="orderStatusRequest" part="OrdersCollection" query="/ns9:OrdersCollection/ns9:Orders/ns9:status"/> </copy> <copy> <from variable="OrderBookingFault" part="payload" query="/client:SOAOrderBookingProcessFault/client:status"/> <to variable="orderStatusRequest" part="OrdersCollection" query="/ns9:OrdersCollection/ns9:Orders/ns9:comments"/> </copy> </assign> <invoke name="SetFaultedOrderStatus" partnerLink="OrderStatus" portType="ns2:OrderStatus_ptt" operation="update" inputVariable="orderStatusRequest"/> </sequence> </scope> </sequence> </catch> </faultHandlers>
Example 7-11 shows the source code for handling a fault using a throw activity in the SOA Order Booking application.
Example 7-11 Source Code for Fault Handling with a Throw Activity
<switch name="taskSwitch"> <case condition="bpws:getVariableData('ApproveOrder_globalVariable', 'payload', '/task:task/ task:systemAttributes/task:state') = 'COMPLETED' and bpws:getVariableData('ApproveOrder _globalVariable', 'payload', '/task:task/task:systemAttributes/task:outcome') = 'REJECT'"> <bpelx:annotation> <bpelx:pattern>Task outcome is REJECT</bpelx:pattern> </bpelx:annotation> <sequence> <assign> <copy> <from expression="string('Order has been rejected by manager')"/> <to variable="OrderBookingFault" part="payload" query="/client:SOAOrderBookingProcessFault/client:status"/> </copy> </assign> <throw name="Throw_1" faultName="client:OrderBookingFault" faultVariable="OrderBookingFault"/> </sequence> </case> <case condition="bpws:getVariableData('ApproveOrder_globalVariable', 'payload', '/task:task/task:systemAttributes/task:state') = 'COMPLETED' and bpws:getVariableData('ApproveOrder_globalVariable', 'payload', '/task:task/task:systemAttributes/ task:outcome') = 'APPROVE'"> <bpelx:annotation> <bpelx:pattern>Task outcome is APPROVE</bpelx:pattern> </bpelx:annotation> <sequence> <empty name="Empty_1"/> </sequence> </case> <otherwise> <bpelx:annotation> <bpelx:pattern>Task is outcome is EXPIRED, STALE, WITHDRAWN or ERRORED</bpelx:pattern> </bpelx:annotation> <sequence> <empty name="Empty_2"/> </sequence> </otherwise> </switch>