Skip Headers
Oracle® BPEL Process Manager Developer's Guide
10g (10.1.3.1.0)

Part Number B28981-03
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

8 Fault Handling

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 run-time faults.

This chapter contains the following topics:

8.1 Use Case for Fault Handling

This chapter uses an example of a credit rating service returning a negative credit message instead of a credit rating number. You also learn how to add a fault handler to a BPEL process to handle the message.

See Also:

The following samples:
  • SOA_Oracle_Home\bpel\samples\tutorials\107.Exceptions

  • SOA_Oracle_Home\bpel\samples\demos\ResilientDemo

8.2 Defining a Fault Handler

Fault handlers define how the BPEL process responds when the Web services return data other than what is normally expected (for example, returning an error message instead of a number). An example of a fault handler is where the Web service normally returns a credit rating number, but instead returns a negative credit message.

Figure 8-1 shows how a fault handler sets the credit rating variable at -1000.

The following code segment defines the fault handler for this operation:

<faultHandlers>
     <catch faultName="services:NegativeCredit" faultVariable="crError">
      <assign name="crin">
         <copy>
           <from expression="-1000">
           </from>
           <to variable="input" part="payload"
               query="/autoloan:loanApplication/autoloan:creditRating"/>
         </copy>
       </assign>
     </catch>
</faultHandlers>

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.

When you select Web services for the BPEL process, determine the possible faults that may be returned and set up a fault handler for each one.

8.3 BPEL Standard Faults

The Business Process Execution Language for Web Services Specification defines the following standard faults in the namespace of http://schemas.xmlsoap.org/ws/2003/03/business-process/:

Standard faults are defined as follows:

8.4 Categories of BPEL Faults

A BPEL fault has a fault name called a Qname (name qualified with a namespace) and a possible messageType. There are two categories of BPEL faults:

8.4.1 Business Faults

Business faults are application-specific faults that are generated when there is a problem with the information being processed (for example when a social security number is not found in the database). A business fault occurs when an application executes a throw activity or when an invoke activity receives a fault as a response. The fault name of a business fault is specified by the BPEL process. The messageType, if applicable, is defined in the WSDL. A business fault can be caught with a faultHandler using the faultName and a faultVariable.

<catch faultName="ns1:faultName" faultVariable="varName">

8.4.2 Run-time Faults

Run-time faults are the result of problems within the running of the BPEL process or Web service (for example, data cannot be copied properly because the variable name is incorrect). These faults are not user-defined, and are thrown by the system. They are generated if the process tries to use a value incorrectly, a logic error occurs (such as an endless loop), a SOAP fault occurs in a SOAP call, an exception is thrown by Oracle BPEL Server, and so on.

Oracle BPEL Server includes several run-time faults. These faults are included in the http://schemas.oracle.com/bpel/extension namespace. These faults are associated with the messageType RuntimeFaultMessage. The following WSDL file defines the messageType:

<?xml version="1.0" encoding="UTF-8" ?> 
<definitions name="RuntimeFault"
  targetNamespace="http://schemas.oracle.com/bpel/extension"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns="http://schemas.xmlsoap.org/wsdl/">

  <message name="RuntimeFaultMessage">
   <part name="code" type="xsd:string" /> 
   <part name="summary" type="xsd:string" /> 
   <part name="detail" type="xsd:string" /> 
  </message>
</definitions>

If a faultVariable (of messageType RuntimeFaultMessage) is used when catching the fault, the fault code can be queried from the faultVariable, along with the fault summary and detail.

8.4.2.1 bindingFault

A bindingFault is thrown inside an activity if the preparation of the invocation fails. For example, the WSDL of the process fails to load. A bindingFault is not retryable. This type of fault usually must be fixed by human intervention. Table 8-1 describes the fault codes.

Table 8-1 bindingFault Fault Codes

Fault Code Description of Fault
VersionMismatch The processing party found an invalid namespace for the SOAP envelope element.
MustUnderstand An immediate child element of the SOAP header element that was either not understood or not obeyed by the processing party contained a SOAP MustUnderstand attribute with a value of 1.
Client.GenericError Generic error on the client side
Client.WrongNumberOfInputParts Input message part number mismatch
Client.WrongNumberOfOutputParts Output message part number mismatch
Client.WrongTypeOfInputPart Input message part type error
Client.WrongTypeOfOutputPart Output message part type error
Server.GenericError Generic error on the server side
Server.NoService Server is up, but there is no service
Server.NoHTTPSOAPAction Request is missing the HTTP SOAP action
Server.Unauthenticated Request is not authenticated
Server.Unauthorized Request is not authorized

8.4.2.2 remoteFault

A remoteFault is also thrown inside an activity. It is thrown because the invocation fails. For example, a SOAP fault is returned by the remote service. A remoteFault can be configured to be retried. Table 8-2 describes the fault codes.

Table 8-2 remoteFault Fault Codes

Fault Code Description of Fault
ConnectionRefused Remote server is unavailable
WSDLReadingError Failed to read the WSDL
GenericRemoteFault Generic remote fault

8.4.2.3 replayFault

A replayFault replays the activity inside a scope. At any point inside a scope, this fault is migrated up to the scope. Oracle BPEL Server then re-executes the scope from the beginning.

8.4.2.4 Catching Run-time Faults Example

BPEL run-time faults can be caught as a named BPEL fault. The bindingFault and remoteFault can be associated with a message. This enables the faultHandler to get details about the faults.

The following procedure shows how to use the provided examples to generate a fault and define a fault handler to catch it. In this case, you modify a WSDL file to generate a fault, and create a catch attribute to catch it.

  1. Import RuntimeFault.wsdl into your process WSDL (located under the SOA_Oracle_Home\bpel\system\xmllib directory).

  2. Declare a variable with messageType bpelx:RuntimeFaultMessage.

  3. Catch it using

    <catch faultName="bpelx:remoteFault"  | "bpelx:bindingFault" faultName="varName">
    

    See Also:

    The following sample, which describes how to handle run-time binding faults:
    • SOA_Oracle_Home\bpel\samples\demos\ResilientDemo

8.5 Getting Fault Details with the getFaultAsString XPath Extension Function

The catchAll activity is provided to catch possible faults. However, BPEL does not provide a method for obtaining additional information about the captured fault. Use the getFaultAsString() XPath extension function to obtain additional information.

<catchAll>
   <sequence>
      <assign>
         <from expression="bpelx:getFaultAsString()"/>
         <to variable="faultVar" part="message"/>
      </assign>
      <reply faultName="ns1:myFault" variable="faultVar" .../>
   </sequence>
</catchAll>

8.6 Using the Scope Activity to Manage a Group of Activities

The scope activity provides a container and a context for other activities. A scope provides handlers for faults, events, and compensation, as well as data variables and correlation sets. Using a scope activity simplifies a BPEL flow by grouping functional structures together. This allows you to collapse them into what appears to be a single element in Oracle JDeveloper.

The following code example shows a scope activity. In this case, the process for getting a credit rating based on a customer's social security number has been placed inside a scope named getCreditRating. This identifies functional blocks of code and sets them apart visually. In Oracle JDeveloper, you can collapse the activities contained inside the scope into a single visual element, or expand them when necessary.

<scope name="getCreditRating">
     <variables>
          <variable name="crError"
            messageType="services:CreditRatingServiceFaultMessage"/>
     </variables>
          <assign name="assign-2">
               <copy>
                   <to variable="input" part="payload"
                    query="/autoloan:loanApplication/autoloan:creditRating"/>
               </copy>
          </assign>
     </sequence>
</scope>

To add a scope activity:

  1. Click and drag a scope activity into the BPEL process diagram.

  2. Open the scope by double-clicking it or by single-clicking the + sign.

  3. Drag activities from the Component Palette to build the function within the scope.

See Also:

The following documentation for examples of creating scope activities in Oracle JDeveloper:

8.7 Throwing Internal Faults

A BPEL application can generate and receive fault messages. The throw activity has three elements: its name, the name of the faultName, and the faultVariable. If 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. Here is a code sample of a throw activity, which includes the fault elements, name, and partner link of the service to which the BPEL process sends the fault, and the copy rule that packages the message:

<throw name="delay" faultName="fault-1" faultVariable="fVar"/>
     <invoke name="invokeStockQuoteService" partnerLink="StockQuoteService"/>
     <assign>
        <copy>
           <from variable="response" part="result" query="/result"/>
           <to variable="output" part="payload" query="/tns:result"/>
        </copy>
     </assign>

See Also:

The following documentation for examples of creating throw activities:

8.8 Returning External Faults

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.

8.8.1 Returning a Fault in a Synchronous Interaction

The syntax of a reply activity that returns a fault in a synchronous interaction is as follows:

<reply partnerlinke="partner-link-name"
       portType="port-type-name"
       operation="operation-name"
       variable="variable-name" (optional)
       faultName="fault-name">
</reply>

Always returning a fault in response to a synchronous request is not very useful. It is better to make the activity part of a conditional branch, where the first branch is executed if the data requested is available. If the requested data is not available, then the BPEL process returns a fault with this information.

See Also:

8.8.2 Returning a Fault in an Asynchronous Interaction

In an asynchronous interaction, the client does not wait for a reply. The reply activity is not used to return a fault. Instead, the BPEL process returns a fault using a callback operation on the same port type that normally receives the requested information, with an invoke activity.

See Also:

8.9 Using a Fault Handler within a Scope

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. To prevent this, contain the parts of the process that have the potential to receive faults within a scope. As described earlier, the scope activity includes fault handling capabilities. The catch activity works within a scope to catch faults and exceptions before they can throw the entire process into a faulted state.

You can use specific fault names in the catch activity to respond in a specific way to an individual fault. To catch any faults that are not already handled by name-specific catch activities, use the catchAll activity.

See Also:

The following documentation for examples of creating fault handling:

8.9.1 Using the Empty Activity to Insert No-Op Instructions into a Business Process

There is often a need to use an activity that does nothing. An example is when a fault must be caught and suppressed. In this case, you can use the empty activity to insert a no-op instruction into a business process. The syntax to use an empty activity is as follows:

<empty standard-attributes>
    standard-elements
  </empty>

If no catch or catchAll is selected, the fault is not caught by the current scope and is rethrown to the immediately enclosing scope. If the fault occurs in (or is rethrown to) the global process scope, and there is no matching fault handler for the fault at the global level, the process terminates abnormally. This is as though a terminate activity (described in "Using the Terminate Activity to Stop a Business Process Instance") had been performed.

Consider the following example:

<faulthandlers>
   <catch faultName="x:foo">
         <empty/>
      </catch>
   <catch faultVariable="bar">
         <empty/>
      </catch>
   <catch faultName="x:foo" faultVariable="bar">
         <empty/>
      </catch>
   <catchAll>
         <empty/>
      </catchAll>
</faulthandlers>

Assume that a fault named x:foo is thrown. The first catch is selected if the fault carries no fault data. If there is fault data associated with the fault, the third catch is selected if the type of the fault's data matches the type of variable bar. Otherwise, the default catchAll handler is selected. Finally, a fault with a fault variable whose type matches the type of bar and whose name is not x:foo is processed by the second catch. All other faults are processed by the default catchAll handler.

8.10 Using Compensation After Undoing a Series of Operations

Compensation occurs when the BPEL process cannot complete a series of operations after some of them have already completed, and the BPEL process must backtrack and undo the previously completed transactions. For example, if a BPEL process is designed to book a rental car, a hotel, and a flight, it may book the car and the hotel and then be unable to book a flight for the right day. In this case, the BPEL flow performs compensation by going back and unbooking the car and the hotel.

You can invoke a compensation handler by using the compensate activity, which names the scope for which the compensation is to be performed (that is, the scope whose compensation handler is to be invoked). A compensation handler for a scope is available for invocation only when the scope completes normally. Invoking a compensation handler that has not been installed is equivalent to using the empty activity (it is a no-op). This ensures that fault handlers do not have to rely on state to determine which nested scopes have completed successfully. The semantics of a process in which an installed compensation handler is invoked more than once are undefined.If an invoke activity has a compensation handler defined inline, then the name of the activity is the name of the scope to be used in the compensate activity. The syntax is as follows:

<compensate scope="ncname"? standard-attributes>
    standard-elements
  </compensate>

The ability to explicitly invoke the compensate activity is the underpinning of the application-controlled error-handling framework of Business Process Execution Language for Web Services Specification. You can use this activity only in the following parts of a business process:

For example:

<compensate scope="RecordPayment"/>

If a scope being compensated by name was nested in a loop, the BPEL process invokes the instances of the compensation handlers in the successive iterations in reverse order.

If the compensation handler for a scope is absent, the default compensation handler invokes the compensation handlers for the immediately enclosed scopes in the reverse order of the completion of those scopes.

The compensate form, in which the scope name is omitted in a compensate activity, explicitly invokes this default behavior. This is useful when an enclosing fault or compensation handler must perform additional work, such as updating variables or sending external notifications, in addition to performing default compensation for inner scopes. The compensate activity in a fault or compensation handler attached to the outer scope invokes the default order of compensation handlers for completed scopes directly nested within the outer scope. You can mix this activity with any other user-specified behavior except for the explicit invocation of the nested scope within the outer scope. Explicitly invoking a compensation for such a scope nested within the outer scope disables the availability of default-order compensation.

See Also:

8.11 Using the Terminate Activity to Stop a Business Process Instance

The terminate activity immediately terminates the behavior of a business process instance within which the terminate activity is performed. All currently running activities must be terminated as soon as possible without any fault handling or compensation behavior. The terminate activity does not send any notifications of the status of a BPEL process. If you are going to use the terminate activity, first program notifications to the interested parties.

The syntax for the terminate activity is as follows:

<terminate standard-attributes>
    standard-elements
</terminate>

See Also:

The following documentation for examples of creating terminate activities:

8.12 Fault Handling Example

The ResilientDemo sample demonstrates failover fault handling and retry fault handling. Failover allows multiple service implementations to be configured for a partner link. If a retryable run-time fault occurs, then the server tries other service implementations. In retry fault handling, the server retries based on a specified retry interval and retry count. Another kind of fault, a binding fault, can occur if the Web service has been upgraded and the interface has changed. In the ResilientDemo sample, when a binding fault occurs, the document is placed in a dead letter queue using a JMS service. The diagram of ResilientFlow.bpel is shown in .

Figure 8-2 Diagram Window of ResilientFlow.bpel

Description of resilient1.gif follows
Description of the illustration resilient1.gif

The invokeRatingService activity shows the failover feature. The partner link of this invoke has two possible implementations, which are configured in the deployment descriptor file as follows:

<properties id="RatingService">
  <property name="wsdlLocation">
    http://localhost:8080/axis/services/RatingService1?wsdl
  </property>
  <property name="location">
    http://localhost:1234/axis/services/RatingService1
    http://localhost:8080/axis/services/RatingService2
  </property>
</properties>

The preceding code sample shows that two endpoint locations are configured for the RatingService partner link. The first endpoint is a bad URL and the second endpoint is a good URL. Because a remote exception like this is retryable, and there is a second endpoint, Oracle BPEL Server tries to call the second endpoint, at which point, the call succeeds.

The invokeFlakyService activity, expanded in , shows system retry.

Figure 8-3 Retry with FlakyService

Description of resilient2.gif follows
Description of the illustration resilient2.gif

The partner link of this invoke is configured as follows:

<properties id="FlakyService">
  <property name="wsdlLocation">
     http://localhost:8080/axis/services/FlakyService?wsdl</property>  
  <property name="location">
     http://localhost:2222/axis/services/FlakyService</property>
  <property name="retryMaxCount">2</property>
  <property name="retryInterval">60</property>
</properties>

If the service is not listening on port 2222, then the invoke fails with a ConnectionRefused run-time fault. Because this is a retryable fault, and the retryMaxCount (set to 2) and retryInterval parameters (set to 60) are defined, Oracle BPEL Server retries twice, with 60 second intervals between each attempt. The second retry is successful.

See Also:

The following sample:
  • SOA_Oracle_Home\bpel\samples\demos\ResilientDemo

  • SOA_Oracle_Home\bpel\samples\demos\ResilientDemo\ResilientFlow\ResilientFlow.pdf for instructions

8.13 Summary

BPEL supports fault handlers to cope with faults, errors, or exceptions returned by the called Web services. This chapter demonstrates the application of a fault handler, a fault handler's structure, and how to create a fault handler in a BPEL process.