Continuing from our previous part we will use the same example to understand the exception handling and cancellation mechanism in WF programs. Exception handling in concept is pretty much the same as in programming languages and emulates similar behavior for easy adaptation. Cancellation is, on the other hand, something we don't deal with regularly.
So let's look at the familiar exception handling first. In WF exception handling is implemented in similar fashion at the level of a block of activities such as sequence or parallel or the whole workflow itself. Let's take the previous example:
and place and exception in one of the activities. I'll add it to the codeActivity1.
Let's run it and by default it should be caught by the runtime, though our workflow would crash.
Now let's catch it within our workflow so that we can do something about it. For that you need to right click on the workflow level and select View Fault Handler, this would show something like the following:
Here we need to drop a fault handler from the toolbox. Then we can put whatever activities we need to handle this error, it could be a whole workflow in itself. But for the moment let's just go with a code activity.
For the first red bubble you need to specify the FaultType this handler is supposed to "catch" and for the second you just need a event handler. Let's assign the FaultType to System.Exception which we raised in our workflow.
In the handler put the following code:
Let's run it.
Now instead of the original error we see the message we printed, hence we can catch any errors and take whatever action we need to rectify it. But as I said, exceptions can be caught at any block level which means that we can localize the error handling to the block where it occurred. Let's do that:
Follow the same process as before and write a handler for it, run it and see that now you can catch it locally.
With exception handling taken care of we move to cancellation. Now cancellation is not your usual programming language feature. A cancellation occurs when you have multiple active branches in the same workflow (for example using parallel) and one of them throws up an error. The branch with error gets an exception but other branches get a cancellation. For us to test this functionality we need two simultaneously executing branches, so we'll use our parallel activity. Move the line that throws the exception from code activity one to two. Put a cancellation handler on the other branch of the parallel activity. Also change the exception condition to avoid skipping it.
As opposed to exception handling, cancellation is a general event hence you just need to add whatever activities that you need to clean up after this cancellation.
Let's add the following code to the code activity:
and run it.
So the second branch was canceled, its cancellation handler called and then the exception was escalated to the level where it was caught by some handler.
Before we conclude this post let's look at another way to raise the exception that we did through code because many times it is done intentionally to signal known error conditions. For that you have the Throw activity. Drop a throw activity after code Activity 2 where we raised the last error and removed the line from code that raises the exception.
Now the code activity will perform its usual function while the error would be thrown by our new activity. We now just need to specify what error to throw. Go to the properties of the Throw activity and set the following:
Now run the code to see cancellation and exception handling. If you would like to throw this error on the same condition as before you will have to drop another If-Else here. This concludes the fourth part of this series. In the next part we will look at writing custom activities.