This chapter will discuss some topics that I think it is important to be aware of if you are designing business processes using BizTalk Orchestration. Error Handling When you perform non-trivial operations in an orchestration you should always be prepared for handling errors, i.e. exceptions. The most obvious place where an exception may be thrown in when you are using Expression shapes to call a component. You may also receive exceptions in numerous other shapes, e.g. Call Orchestration, Transform and Message Assignment. If you do not handle errors that occur in an orchestration they will fail the entire orchestration and the raw message of the exception will be logged by BizTalk. This is not a completely bad thing, but I think that you should try to log a better error message with BizTalk that explains a bit more what has happened. Using a Scope with Exception Handler To handle exceptions in BizTalk Server you use the Scope shape and add an Exception Handler to it, you do so by right-clicking on the Scope and selecting New Exception Handler. Inside the Scope shape you add other shapes that you suspect may throw exceptions which you wish to handle. For each Exception Handler that you add you need to define which type of exception that it will catch, along with the name of the variable in which it will be stored, you set this in the Properties window. I suggest that you always catch System.Exception and name the variable ex, follow these steps: 1. 2. 3. 4. 5.
6.
Click in the Exception Object Type field. Click on the selection button. Select <.NET Exception...> from the menu, see picture below. Select Exception from the list of types in the Select Artifact Type window, it's located in mscorlib if you have trouble finding it. Press OK. Select the Exception Object Name and type ex.
If you have multiple Exception Handlers you should specify different Exception Object Type for each of the handlers, begin with the most specialized exception type and always catch System.Exception in the last handler. Below are four examples of how you can use Exception Handlers:
• •
•
The first example is of how you may ignore an exception. The handler only contains a Trace Point so BizTalk will consider this exception to be fully handled and therefore it will continue with the next shape below the Scope shape, just as if no exception had occurred. The second example uses a Terminate shape to terminate execution of this orchestration instance. When using a Terminate shape you must specify an error message that will be logged with BizTalk (it will be visible in HAT). To create this message you should use the information available in the exception variable. Example of messages are: o ex.ToString() o "OrchestrationName failed when calling helper component: " ex.ToString() The third example uses a Throw shape to rethrow the exception. This causes the exception to propagate to the next level of Exception Handler, and if there are no more handler it will terminate the orchestration instance.
•
The last example illustrate the usage of multiple Exception Handlers. In this example we ignore the first type of exception (NetologiException), but if an exception other then that occur we rethrow the exception.
A Scope shape may also have a Compensation Block associated to it, they are optional to use and there may only be one Compensation Block for a Scope (as opposed for Exception Handlers that may occur multiple times). I do not intend to discuss usage of Compensation Blocks here as my experience with them are limited. Global Exception Handling As a precausion for unexpected errors you should always include a Scope shape that (almost) covers the entire orchestration, I call this a Global Exception Handler. The purpose of this error handler is to allow you to properly log the event, not to handle the exception. Below is an example of what my orchestrations look like when a Global Exception Handler had been added. At the top is the activating Receive shape that received the incoming message and below it is an Expression shape that retrieves the unique identifier of the message (if you have one in your message) and stores it in a variable that has orchestration scope. When an exception is thrown that reached the Global Exception Handler I trace the unique identifier along with the actual error. By including the unique identifier in the trace I can easily see which message failed, without searching through HAT.
Using the Decide Shape The Decide shape is one of the simplest shapes to understand in BizTalk Orchestration, as it provides the functionality of the if-statement (which most developers are familiar with :-). When you drop a Decide shape into the orchestration you will by default get two branches, called Rule_1 and Else. Through double-click on the Rule_1 shape you will be shown a window that allow you to enter a boolean expression that will be used to decide if the branch should be executed or not. You should be aware of the a Decide shape always must contain the Else branch along with at least one other branch. Even though it is required to have an Else branch there is no requirement to have any shapes in it, i.e., you may use an empty Else branch as "fall through" to the next set of shapes. Ta add additional branches to the Decide shape you right-click of the shape and select New Rule Branch.
The picture above illustrate usage of the Decide shape to check the state of an object. If the state is Approved or Denied the associated branches will execute, but if state is Postponed no actions will be taken and execution will continue with the shape that is immidiately below the Decide shape. The last branch, the Else, terminates execution of the orchestration as this was an unexcepted state, see below for more discussion on this topic. To summarize, using the Decide shape you may construct if-else or if-else if-...-else if-else statements. Each branch, including the Else branch, may contain zero or more shapes that allow you to support both fall-through as well as an arbitrary complex flow. Checking Non-Numeric Values In most cases when I have used the Decide shape it has been to test for equality of a nonnumeric value, i.e. string or enum values. A problem that may occur when using non-numeric values is that the valid set of values change, perhaps without your knowledge! An example could be that the valid states in the picture above is expanded with with the state Tentative, what would you like to happen to your orchestration if an unexpected state suddently was used? I think that if that were to occur then the solution is not to let it pass through just as if nothing unexpected hadd happened. I expect an error to occur that says that an unexpected state was used, then it's up to the person responsible for the solution to analyze this error and decide whether this was a temporary error or is due to that the orchestration has not been updated along with the components on which it depends. If a dependency component is updated is a way that affect the functionality of the orchestration then you'll need to update the orchestration and redeploy it! To ensure that an error occur in these situations I recommend that always use the Else-branch to terminate the orchestration if an unexpected state is found. Using the Listen Shape One of the most important shapes in BizTalk is the Listen shape, you'll need to understand how to use it to be able to efficiently design orchestrations. It's importance becomes evident when you need to support a business process that has limitations in how long a certain part of the process may take. An example could be an process where a manager is supposed to approve a purchase order, but if he hasn't done so in 24 hours a substiture approver should be notified. The Listen shape allows you listen for one or more events, using Receive shapes, while at the same time a Delay shape is used to limit the total time taken to complete the operation. Each
of these sub-processes is called a branch, the Delay shape is one branch and the Receive shapes is one branch. The functionality of the Listen shape is to wait for one of these branches to to complete, when the first branch completes the orchestration continues with the next shape. Compare this with the Parallel shape where you do not continue with the next shape until all branches of the Parallel shape has completed.
In the picture above we wait for 24h for a response to an approval task, if the response is available within 24h the shapes in the Handle Decision Group shape is executed. However, if no response has arrived within 24h the Expression shape that sets the state to Timeout is executed and execution of the orchestration continues without further waiting for a response on the approval task. I believe that you will find use of the Listen shape in many of your orchestrations that include interaction with real people. They will not be as frequently used when you are dealing with machine-machine communciation.