Introduction

This is part 3 of my 3 part series on exception handling with the ESB Toolkit. In this last article I will explain how to create your own error messages when your service fails. That is, when an error occurs in one of you own components… how do you handle this?

I’m not the first person to look at this and I took some of the ideas that Paolo Salvatori blogged about here.

The Problem - Catching Exceptions

Here is the scenario I was working on when I discovered the problem. You can see that I have a BizTalk service. I have exposed this as a WCF service.

During my testing of this service, I wanted to check that it provided the desired response when an error occurred within my itinerary. I found that the response I got contained information that I didn’t want my consumers to receive. For instance, when a map failed, the full reason for failure was available to my consumer. This is pretty much standard BizTalk pipeline behavior. However, what I wanted to do is hide the details of the error from my consumers.

Itinerates 101

Before we continue, I just want to reiterate here that itinerates execute in BizTalk pipelines. So, when an error occurs in you itinerary there is no way to catch the exception and you can’t the do anything with it. To overcome this, we need to configure a hook into the adapter to get to the exception.

The Solution – WCF Error Handler

I took the advice from Paolo and created my own IErrorHandler. In it I take any errors and convert them to a SOAP Fault. I was looking for a generic solution and decided that this was best. From there, I extended Paolo’s idea and added the ability to execute a map in the error handler. Here’s how I got it working.

Step 1 – Create the Error Handler

I’m still using BizTalk 2009, Visual Studio 2008 and the ESB Toolkit 2.0 but I’m sure you can get this to work with 2010 and 2.1 respectively.

So, I have a plain old assembly that contains the following types.

The solution all starts with the ErrorHandlerBehaviorExtensionElement class. This is a configuration element that we will be referencing when we setup our receive port. I have added a custom property to this class so that we can configure an optional map to execute after the exception has been converted into a SOAP Fault.

The Extension Element provides an instance of the ErrorHandler class which implements both IServiceBehavior and IErrorHandler. The error handler will convert the exception into a SOAP Fault by using the ErrorBodyWriter. It will also execute a map if configured.

The ability to execute a map has been provided because the Error Handler is executed in the bowels of the WCF adapter. It is no longer in BizTalk or even a pipeline and, as such, we loose any ability to process the message via an itinerary or orchestration.

Implementing of the IErrorHandler is where the guts of the solution sits. Here is the interface of the IErrorHandler.

For the HandlError method, I just trace the error for debugging purposes. In the ProvideFault method is where we create our custom response message. Here is the code:

I use a private method called CreateErrorMessage that creates a response message for us. In it, I manually execute a custom BodyWriter to build my fault. I then pass the result from the BodyWriter to a map if needed.

If we have the details of a map, then the ErrorHandler attempts to execute it. Any errors that happen when executing the map are ignored. We use some of the runtime types that you get with BizTalk to perform the mapping. Here is the method that does this.

I need to point out that our BodyWriter doesn’t produce the full SOAP Envelope as the BodyWriter in from the first article in this series does. This is because the error handler is only required to build the message body not the whole message envelope as we needed in part I.

Only adding this to the BizTalk config file means that it won’t be accessible to IIS or the BizTalk console.

Remember to add this to both the 32bit and 64bit machine.config files if you are running a 64bit OS.

Also, remember to restart IIS and all BizTalk hosts to pick up the config file changes.

Step 3 – Creating your BizTalk Application

The next step is to create a BizTalk application called ESB.ExceptionHandling.

I have taken the schema from part I of this series and, have created an example a map that I know will fail. I also use the SOAP to Response map I created in part I. The schema and maps have been deployed to BizTalk and will be executed by my itinerary.

My port configuration includes a WCF receive port called TestReceivePort with a receive location called TestReceiveLocation. The receive location uses the ItinerarySelectReceiveXml pipeline with the following settings:

Property Name

Value

ItineraryFactKey

Resolver.Itinerary

ResolverConnectionString

ITINERARY:\\name=ESB.ExceptionHandling.Test

To make use of the custom error handler, I have used WCF-CustomIsolated for the receive location type. This has been configured to use wsHttpBinding and I have set security to None.

Then I add the custom behavior extension on the behaviors tab.

I configure the error handler to execute my SOAPFault_to_Response map from part I by entering the full type of the map.

Lastly, I make sure that the error handling includes the fault details.

I published the receive location to IIS using the WCF Publishing wizard and can now use soapUI to consume my service.

The rest is pretty much standard ESB service configuration.

Step 4 – Building your itinerary

Now we are ready to build our itinerary. Here is what mine looks like. It’s basically a pass-through service with a transform before the off-ramp.

The transform will fail because we will use my map that I know will fail. The off-ramp will never be reached so I’m not going to go into its configuration.

Once you have the itinerary, you can deploy it as normal and you’re ready to test.

Step 5 – Testing

As before, I use soapUI to test my service. The result I get when I call my service conforms to my response schema as below. The map generated an error that was converted to a SOAP Fault which, in turn,

Share

About the Author

I have almost 20 years commercial software development using a number of languages from C++ to C#/VB. My main focus has been in the Microsoft space and, since the early 2000's, most of this has been in the web or integration arena. Over the past few years I have been focusing on building business solutions using a variety of products such as BizTalk and Share Point.
In terms of SDLC's, I have experience with various methodologies such as Agile, RUP, Iterative and Waterfall.
Lastly, the roles I have had in the last few years have given me the opportunity to gain a lot of experience as a consultant. Since, over the last 18 years, I have worked with many customers this has further given me the chance to enjoy many and varying challenges that have helped me grow in my career.
Today, I spend a lot of time talking, designing, documenting and mentoring team members. I also spend quite a bit of time authoring software and find the combination a perfect fit for me.