How to handle exceptions

There are two categories of exceptions that a collaboration can handle:

When an exception occurs, the exception handling at a given level of the activity-diagram hierarchy can handle this exception in one of the following ways:

Not catching the exception

If the activity diagram does not explicitly catch the exception with an exception branch, the collaboration's execution remains in the Exception state (which it entered when the exception occurred). The collaboration runtime environment does not stop execution in the diagram when the exception occurs. Instead, execution continues according to the logic of the activity diagram, ending in either an End Success or an End Failure node:

Catching the exception

A collaboration template can incorporate exception handling in its activity diagram with exception branches, which are branches within a decision node whose branch type is set to Exception. The decision node connects the action symbol to its possible decision outcomes. An exception branch routes the action symbol in which the exception occurs to the action symbol in which the exception is handled. An exception branch includes an exception condition, which specifies the exception type that the exception branch catches. Table 31 lists the collaboration exception types that you can choose from when you define the exception condition.

Note:
For more information on how to add an exception branch to an activity diagram, see Defining an exception branch.

When an exception occurs, the collaboration runtime environment populates the currentException system variable. To determine whether to follow the exception branch, the collaboration runtime environment evaluates the exception condition of the exception branch by comparing the exception type in the exception branch's condition with the exception type in the currentException system variable:

Note:
The collaboration runtime environment checks for exception branches only when the collaboration execution is in the Exception state.

A given decision node can have a maximum of seven branches. Therefore, it can provide exception-handling for many exception types. Each exception branch can specify a different exception type in its exception condition and can point to an exception-handling node for that exception type. Alternatively, you can handle all exception types in a single exception branch that has the AnyException exception type in its exception condition.

Once the collaboration template has caught the exception and execution passes to the exception-handling node, the collaboration template can handle it in the following ways:

Proceeding with scenario logic

To proceed with the logic of the scenario, you take the following steps in the exception-handling node:

  1. Process the exception in a manner that does not involve raising the exception.

    Within the node to which the exception branch points, you can include code that processes the exception. Table 32 lists some possible processing steps.

  2. End the execution path in the activity node with either an End Success or an End Failure node.

    As long as the exception-handling node does not raise the exception (with the raiseException() method), the collaboration's execution remains in the Normal state. Therefore, the collaboration runtime environment does not create an unresolved flow when collaboration execution completes. For more information on how the collaboration runtime environment processes these termination nodes, see Processing the Normal state.

Table 32 lists some of the possible processing steps that the exception-handling node can perform. None of these steps changes the collaboration's execution state. Therefore, the collaboration's execution remains in the Normal state.

Table 32. Possible processing steps for exception handling
Exception-handling step Methods For more information
Log a message in the collaboration's log destination. logError(), logWarning(), logInfo() Logging messages
Obtain information about the exception. Methods of the CollaborationException class. Table 30

For example, the logError() method logs errors to the collaboration's log destination. This destination can be standard output (STDOUT) or to a log file, if configured to do so. This method also sends the error message to an email recipient. The collaboration template can use this method to record errors that the administrator can examine. The following code fragment extracts exception information from the currentException variable with the getMessage() and getMsgNumber() methods of the CollaborationException class. It then uses this information to format the error to send to the collaboration's log destination with a call to logError().

// extract exception information
 sMessage = currentException.getMessage();
 imsgNumber = currentException.getMsgNumber();
  
 // log message and send email (if configured)
 logError(imsgNumber, sMessage, ...);
 

For more information, see the description of the logError() method in logError(), logInfo(), logWarning(). Keep in mind that merely sending an error to the log destination is often insufficient for associating a clear exception message with the unresolved flow. For example, suppose that an exception occurs, an exception branch catches it. and the exception-handling node simply logs the error and ends in failure. In this case, the unresolved flow for the unsuccessful collaboration includes the failed event but its exception message is just the collaboration runtime environment's default message (Scenario failed.).

Raising the exception

The raiseException() method raises a collaboration exception to the next higher level of execution. When the collaboration runtime environment executes the raiseException() call, it changes the collaboration's execution state to Exception, then proceeds with the logic of the activity diagram. To raise the exception to the next higher level in the activity diagram, you take the following steps in the exception-handling node:

  1. Acquire exception information from the current exception to include in the raised exception.

    Within the exception-handling node, you can use methods of the CollaborationException class to extract exception information from the currentException system variable.

    Note:
    It is important to extract the message from the currentException variable so that it can be included in the raised exception. By doing so, this message can be available to the collaboration runtime environment when it associates an exception message with the unresolved flow.
  2. Include a call to the raiseException() method to generate the exception to raise.

    When the collaboration runtime environment executes a call to raiseException(), it changes the collaboration's execution to the Exception state. The raiseException() call provides the exception to raise to the next higher level of execution.

  3. End the execution path for the branch that contains the exception-handling code with either an End Success or an End Failure node.

    Because you have raised the exception, the collaboration execution is in the Exception state. As long as each level of execution raises the exception (with raiseException()), the collaboration's execution remains in the Exception state. Therefore, the collaboration runtime environment creates an unresolved flow when collaboration execution completes. For information on how the collaboration runtime environment processes these termination nodes, see Processing the Exception state.

To understand how you can use the raiseException() and logError() methods in collaboration templates to handle exceptions, consider the following example. Suppose that a collaboration's main diagram calls subdiagramA, which in turn calls subdiagramB. SubdiagramB makes a service call, which could result in an exception. Therefore, this subdiagram contains an action node that invokes a service call. This action node connects to a decision node with an exception branch that checks for service-call exceptions. If a service-call exception occurs, the exception branch connects to an action node with the exception-handling code.

When an exception occurs, the collaboration runtime environment changes the collaboration's execution to the Exception state and evaluates the exception condition of any exception branches that are associated with the service call in subdiagramB. If an exception branch's condition evaluates to true, the exception branch catches the exception and control passes to the exception-handling node to which this exception branch points. Once the exception branch catches the exception, the collaboration's execution returns to the Normal state.

Figure 51 shows the code fragment that performs the exception handling for a service-call exception in subdiagramB.

Figure 51. Handling the service-call exception in subdiagramB

// exception handling in subdiagramB
 sMessage = currentException.getMessage();
 sType = currentException.getType();
  
 // raise the exception to subdiagramA
 raiseException(sType, 2345, parameter1, parameter2, sMessage);
 }
 

The code in this exception-handling node takes the following steps:

  1. Check the currentException system variable for information about the exception.

    The code obtains the exception message and exception type from currentException and saves them in two string variables (sMessage and sType, respectively).

  2. Raise the exception to the parent diagram (in this case, subdiagramA).

    Once it gathers the exception information, the code calls the raiseException() method to raise the exception to subdiagramA. This form of the raiseException() method receives the exception information as an exception type and an error message (2345) with its three message parameters. These message parameters include the exception message that the code obtained from the currentException system variable. The raiseException() call then creates an exception that contains this exception information. It also changes the collaboration execution to the Exception state.

    Notes:

    1. The number of message parameters that raiseException() provides for a message depends on the particular format of the message in the collaboration message file.

    2. You can specify the same exception types when you raise an exception in the exception-handling code with the raiseException() method as you can when you define the exception condition in the exception branch. For a list of exception types, see Table 31.

After raiseException() executes, the action that the collaboration runtime environment takes depends on the termination node that ends the execution path. If the execution path terminates in an End Success node, the collaboration runtime environment takes the following steps:

Note:
If the execution path terminates in an End Failure node, the collaboration runtime environment terminates the entire collaboration. Because the execution state is Exception, the runtime environment creates an unresolved flow using the exception information in the exception that the raiseException() call raised.

If a decision node with exception branches exist in subdiagramA, the collaboration runtime environment evaluates each exception branch's condition. If this exception condition evaluates to true, subdiagramA catches the exception that subdiagramB raised. The collaboration execution changes to the Normal state and control passes to the exception-handling node, which handles the exception by raising it up to the parent diagram (the main diagram) with the following call to raiseException():

// exception handling in subdiagramA: raise the exception to main diagram
 raiseException(currentException);
 

This form of the raiseException() method just raises the exception object that it receives as an argument. It does not create an exception from information passed in. In this case, there is no need for raiseException() to create an exception because the exception-handling code in subdiagramB (Figure 51) has already created the exception with the appropriate exception information. The exception that subdiagramA has in its currentException variable is the same exception that subdiagramB raised. After the raiseException() completes, the collaboration execution continues according to the logic in subdiagramA. If this exception-handling branch of subdiagramA ends in End Success, the collaboration runtime environment terminates subdiagramA and passes control to its parent diagram, which is the main diagram. Therefore, the exception object that raiseException() generates (the currentException exception object in subdiagramA) is now raised to the main diagram.

Note:
If this exception-handling branch of subdiagramA ended in End Failure, the collaboration ends and the exception object is raised to the collaboration runtime environment, which includes its exception message as part of the unresolved flow.

Collaboration execution is currently at the subdiagramA node in the main diagram. The collaboration execution is currently in the Exception state because the exception-handling node in subdiagramA called raiseException(). Therefore, the collaboration runtime environment checks in the main diagram for any exception branches that catch the raised exception. These exception branches would be within a decision node that connects the call to subdiagramA to one or more exception-handling action nodes. If an exception branch's condition evaluates to true, the main diagram catches the exception that subdiagramA raised. The collaboration's execution changes to the Normal state and control passes to the exception-handling node, which can take the appropriate high-level exception-handling steps.

As an example, suppose that this exception-handling node in the main diagram takes the following steps:

  1. Verify whether the collaboration's SEND_EMAIL configuration property is set to either all or a comma-delimited list of message numbers.

    All collaboration objects can indicate the recipients of email for errors that the logError() sends to the log destination. If a collaboration is based on CollaborationFoundation, it can take advantage of the additional functionality that the SEND_EMAIL collaboration property provides. If the collaboration object is configured to send email and SEND_EMAIL is set to either all or a list of message numbers, the collaboration sends email to the specified recipients when any error (SEND_EMAIL is all) or a specified error (SEND_EMAIL provides a message-number list) occurs.

    If these conditions are met, the exception-handling node should call logError() to log the error and send email to the specified recipient. Therefore, the code must first retrieve the exception information to include in the error message from the current exception.

    Note:
    The SEND_EMAIL configuration property is a feature of the CollaborationFoundation. If your collaboration is based on CollaborationFoundation, it can perform this checking of the SEND_EMAIL property. Otherwise, this configuration property is not defined.
  2. Send the exception message to the collaboration's log destination and as an email message, if appropriate.

    If the collaboration object is configured to send email, the logError() method automatically sends the error message to a specified email recipient. This branch uses the logError() method to send the exception to the collaboration's log destination (standard output or a log file).

The following code fragment in the exception-handling node of the main diagram performs these steps:

// exception handling in main diagram
  
 // determine if SEND_EMAIL is set to "all" or a message-number list;
 // if so, obtain exception information from the current exception
 sMessage = currentException.getMessage();
 imsgNumber = currentException.getMsgNumber();
  
 // log message and send email
 logError(imsgNumber, sMessage, ...);
  
 // raise the exception to collaboration runtime environment 
 raiseException(currentException);
 

When the collaboration runtime environment executes this raiseException() call, it takes the following steps:

When the administrator views unresolved flows, the Flow Managers tools shows this unresolved flow's message (obtained from the exception when it first was thrown, down in subdiagramB).

Copyright IBM Corp. 2003, 2004