Handling particular service-call exceptions

When a collaboration sends a business object request to its destination application, the collaboration runtime environment indicates any failure by throwing a collaboration exception with an exception type of ServiceCallException. However, the cause of a service-call failure can be ambiguous. A service call might fail for the following reasons:

This section provides information about how to handle the following service-call error conditions in your collaboration template:

Service calls and exactly-once requests

The potential for duplication of data can occur in any of the following situations:

Preventing duplication of data due to transport-related exceptions must be handled at both of the following points:

The next sections describe how to handle the transport-related exceptions.

Handling runtime transport-related exceptions

To prevent duplication of data from a transport failure that occurs at collaboration runtime, code your collaboration template to distinguish after each service call between a transport-related exception and one that is not transport-related. To check for a transport-related exception, use the ServiceCallTransportException subtype of the ServiceCallException exception type. This exception subtype indicates that there was an error in the transport, and that it cannot be determined with certainty whether the request reached the application.

Important:
A subset of exception types that previously were represented by the AppUnknown subtype of ServiceCallException are now represented by the ServiceCallTransportException subtype. Therefore, a collaboration template that checks specifically for the AppUnknown subtype must now also check for ServiceCallTransportException. Because the AppUnknown subtype no longer handles transport exceptions, the collaboration object will not trap transport exceptions if it checks for all subtypes except ServiceCallTransportException.

Handle a transport-related exception in the node immediately following the exception branch; that is, the node to which the exception branch points. Code the exception-handling node that catches an exception with the ServiceCallException exception subtype to provide an extra Retrieve service call that retrieves the request business object from the destination application and determines whether the application successfully created or modified the object. If the object was not created or modified successfully, code the collaboration to re-try the request.

The following code fragment provides exception handling for a transport-related exception. It uses the getSubType() method to retrieve the exception subtype from the currentException system variable. If this exception subtype is ServiceCallTransportException, the exception-handling code must perform a retrieve to determine whether data has changed in the application as a result of the service call request.

if (currentException.getType().equals(ServiceCallException)) {
     if (currentException.getSubType().equals(
         ServiceCallTransportException))
     {
         //Perform a retrieve to determine whether data changed
     //in the application reflecting the ICS business object request
     }
     else
         raiseException(ServiceCallException, ...);
 }
 

Note:
Checking for a transport-related exception is particularly important if the collaboration connects to the destination application over an unreliable network. In such a case, it is important to retry every time this exception could occur. Because the code can check specifically for exceptions caused by transport failure, there is a much lower performance impact than if your code performs the retry for all exceptions.

Handling boot-time recovery transport-related exceptions

To prevent duplication of data for a failure that results from a crash of InterChange Server while a collaboration service call was in process, you can do either of the following:

Transactional collaborations

When InterChange Server recovers a transactional collaboration that specifies compensation for every service call includes rolling back the collaboration before resubmitting the failed request. Because of the rollback, duplication of data for a failure resulting from a server crash is not a problem. For more information, see "Using transactional features".

Non-transactional collaborations

Recovery of a non-transactional collaboration does not include rolling back the collaboration before resubmitting the failed request. Therefore, duplication of data can be a problem. To prevent data duplication for a non-transactional collaboration, configure the collaboration object for Service Call In-Transit persistence. On the Collaboration Properties dialog, check the box labelled:

Persist Service Call In Transit State
 

For backward compatibility with existing collaborations and because transactional collaborations do not benefit from persistent storage of each service call state, the default setting for Service Call In-Transit persistence is off; that is, the Persist Service Call In Transit State box is not checked for a collaboration object.

When a collaboration object that has been configured for persistence enters a service call, ICS maintains the state of the request until it has been completed. If the server crashes while a collaboration is processing a service call, the state of that failed service call is displayed in the Flow Manager, with the following status:

In this case, the administrator must manually determine whether the collaboration request was successfully processed before the transport failure. If the request was not successful, the administrator should resubmit it. For more information, see the System Administration Guide.

Note:
If a collaboration is not configured for Service Call In-Transit persistence, all runtime failures and exceptions that cause the flow to fail have an event status of "Failed" in the Unresolved Flows viewer.

Unsent service call requests

To verify that the service call request has been sent to the application, code your collaboration template to check after each service call. To verify that the request has been sent, use the AppRequestNotYetSent subtype of the ServiceCallException exception type. In the case of a parallel connector agent, this exception subtype indicates that the request was queued up in the agent master but never got dispatched to the application; therefore, you can resend the request.

Handle an unsent service-call exception in the node immediately following the exception branch; that is, the node to which the exception branch points. Code the collaboration template to resubmit the request. The following code fragment provides exception handling for an unsent service call request. It uses the getSubType() method to retrieve the exception subtype from the currentException system variable. If this exception subtype is AppRequestNotYetSent, the code must resubmit the event by returning to the action node with the service call.

if (currentException.getType().equals(ServiceCallException)) 
 {
     if (currentException.getSubType().equals(
         AppRequestNotYetSent))
     {
     // Resubmit the event by returning execution to the action node
     // with the service call.
     }
     else
         raiseException(ServiceCallException, ...);
 }
 

Important:
The collaboration runtime environment does not set a value for the AppRequestNotYetSent subtype if the ControllerStoreAndForward connector property of the destination connector is set to true. If this connector property is set to false, the collaboration should check for this subtype and resend the request.

Copyright IBM Corp. 2003, 2004