Category: Exception Handling


Welcome back to the “Throwing typed WCF faults back to consumers in a BizTalk messaging only application” blog series.  This is the 2nd part in the series and specifically focuses on creating and publishing your typed fault so that it is available for use in further sections of the series.  If you haven’t yet read the prior entries in this series then follow the below links before you continue reading this entry.

Part 1 : Introduction

First things first, we need to create a class representation of the typed fault that we want to throw back to service consumers.  The details I want to share with consumers are a fault code, the list of possible fault codes being shared with service consumers through interface documentation, a reason, which serves as a summary of the error, and a message which contains the details about the particular fault.  In the case of an XML schema validation failure the object might be populated with a fault code of XMLVAL, a reason of Schema Validation Failure, and a message describing exactly which node in the XML message caused the problem and what the schema violation was.  Once the class has been created, the project should be built with a strong name key and the assembly should be added to the GAC.

Note that your class does not need to inherit from the System.Exception base class (in fact this might cause problems for the XML serializer, it definitely causes problems with the XSD.exe tool).  Rather it can be your own custom class with no inheritance requirements.

A few important notes.

  • In order for your class to be serializable it must implement a default constructor.
  • You will want to decorate your class with a DataContract attribute.  You might want to specify the Name property on the DataContract attribute if you want to use a friendlier name in your serialized XML representation of the class rather than the class name.  You will definitely want to specify a Namespace to avoid clashes with other classes with the same name.
  • Likewise you will want to decorate any properties in your class that you want to get serialized into your XML with a DataMember attribute.  I make it a habit to specify the Order property on the DataMember attribute to explicitly state how I want elements to be ordered in the XML rather than leaving it to the serializer to decide this (I believe the default ordering is alphabetical which might or might not work for you).  As with the DataContract attribute you might choose to override the Name of the element in the serialized XML.

After taking the above into account my class looked like the below.

ExceptionClass

In preparation for the next post in the series I used the XSD.exe command line tool to generate the schema representation of this class and added it to a BizTalk project which I would then deploy to my environment.  In order to do this I had to browse to the bin\debug folder into which the assembly that contains aforementioned custom exception class gets built to in a Visual Studio Command Prompt, and run the following command – “xsd.exe {Assembly name}.dll /type:{Fully qualified class name}”.  This utility will generate an XSD file in the same folder location which you can then rename appropriately and copy to the relevant BizTalk project folder and add it to your project.  What I did find was that the generated schema had an empty target namespace (possibly due to a mistake I’ve made in my exception class but I haven’t had time to figure that step out yet) so I added that to the schema manually.  The schema now looks like the below.

ExceptionSchema

We now have a custom exception class and schema created that represents our typed fault, which we can expose in the service’s WSDL and return in place of out of the box BizTalk exceptions which will be explored in the next entries in this blog series.

If you are interested in reading further then do follow the links to further entries in this blog series.

Part 3 : Publishing the typed fault contract in the WSDL

Part 4 : Creating a custom error handling service behavior

Part 5 : Creating an endpoint behavior to copy headers and the SOAP action from the request to the response

Part 6 : The client experience

An interesting challenge I have recently faced has inspired me to get back to the blog after a bit of a hiatus (my wife and I are expecting our first child very soon so blogging opportunities might be rare for awhile) and share some interesting experiences I’ve encountered on a recent project.  I have been tasked with standing up public facing one-way BizTalk WCF services that make use of a custom WCF behavior for authorization purposes, a schema validation pipeline component and the BRE Pipeline Framework for more complex validation.  The idea is that if any of the validations fail BizTalk should not accept the message and should instead return a fault to the client, and if all the validation succeeds then BizTalk sends back an empty response to the client (remember that a one-way BizTalk WCF receive location still involves a response being returned, it’s just that the response is empty).

With a naive outlook this is very easy to implement. All you have to do is turn on “Include Exception Details in Faults” on the messages tab of the receive location configuration and any exceptions encountered on your WCF receive location will now result in a SOAP fault being returned to the client with the exception contained within the details section of the message.

IncludeExceptions

However there are many problems with this approach.

  • The exception in the message details section contains way too much information, including the pipeline name and fully qualified assembly details, as well as a stack trace which should be considered sensitive internal information and not shared with consumers.
  • The exception type contained within the fault detail is Microsoft.BizTalk.Message.Interop.BTSException.  I don’t see this as being a good exception type, seeing as I don’t even want my consumers to know that the WCF service they are calling is hosted by BizTalk.  I would much rather throw a meaningful exception type.
  • The exception is not very friendly; while it contains the error details that the service consumer requires to troubleshoot the issue, it doesn’t contain an error code or an error type which the consumers might find helpful.
  • If the client was using a messaging engine like BizTalk rather than calling the service programmatically, and if they wanted to route the error to a exception handler rather than suspend the messaging instance, then they would be forced to make use of an orchestration that persists the identifier fields in the request message, so that they can inject those details into the exception before routing it to the exception handler.  If they didn’t do this (or something else creative) then the exception would contain no context and thus be rather useless to operational staff responding to it.

An example error message that the service would return in the case of an XML validation failure is as below.  Note that the fully qualified pipeline name is included, as is the fully qualified assembly name, the specific pipeline component that failed, and an entire stack trace.  I think almost anyone would recognize that this isn’t good enough for a publicly exposed service.

RawException

I decided to tackle these problems utilizing the below solutions, which I will describe in more detail further into this series.  I am sure there are other ways to approach these issues but this has worked quite well for me.

  1. Create a .NET class decorated with DataContract/DataMember attributes that represents a custom exception and contains all the details that I might want to return to a service consumer.
  2. Expose my custom typed fault in my WSDL to ensure that consumers are able to properly consume the exception detail.  For BizTalk consumers this would mean that generating schemas based on the WSDL via the “Add generated items/Consume WCF Service ” wizard would result in a schema corresponding to the custom exception being created as well.  For .NET (or other programmatic consumers) consumers this would mean that adding a service reference would now result in proxy classes representing the custom exception also being created.  I implemented this with a slight variation to the WsdlExportExtension service behavior described by Paolo Salvotori in this article that describes how to throw WCF typed faults in a BizTalk orchestration solution.
  3. Create a custom service behavior which enlists a custom error handler that inspects the out of the box error that is being returned to the client and replaces it with a new System.ServiceModel.FaultException<CustomException> where CustomException refers to the class that I created in the above step, and then populates the custom exception with the relevant details.
  4. Lastly I implemented an endpoint behavior that kills two birds in one stone.  First of all the endpoint behavior copies the SOAP action value from the request message to the response.  This is very important as the response message returned by BizTalk must hold the same SOAP action as the original request.  I will explain why this is important and illustrate this with examples further into the series.  The endpoint behavior also copies over a custom header value from the request to the response which provides BizTalk consumers (or other messaging engine type consumers who face a similar challenge) with a means of ensuring that exception messages returned by the service contain enough detail to route the message to an exception handling framework with no enrichment required from the original request.

As this is a rather complex solution and makes for a long read I have broken up this blog post into a series.  While I can’t provide the source code for this solution I shall share some code snippets and implementation details that should help you get going.  If you are interested in seeing how I’ve faced the aforementioned problem then continue on with the following parts of this series.

Part 2: Creating the typed fault

Part 3 : Publishing the typed fault contract in the WSDL

Part 4 : Creating a custom error handling service behavior

Part 5 : Creating an endpoint behavior to copy headers and the SOAP action from the request to the response

Part 6 : The client experience

Most developers who have worked with BizTalk for a while will realize the benefits of using direct binding on orchestration ports to improve flexibility and loose coupling. What is not often realized is that using direct rather than specify later port binding comes with a bit of a trade-off in that the increased flexibility results in less hand holding for administrators, and it is altogether possible for them to stop/unenlist an orchestration or send port resulting in routing failures and unprocessed messages which might be difficult to replay. Seeing as guaranteed delivery is one of the biggest selling points on most projects involving BizTalk Server this is too big a hole to overlook. In this blog post I will detail how hand-holding is relaxed for direct binding and introduce error handling patterns that can be used in orchestrations to overcome routing failures.

One of the things most BizTalk administrators might notice when orchestrations use direct binding is that starting an orchestration no longer require starting all send ports that the orchestration publishes messages to. At run time this could mean that the loose coupling offered by direct binding has removed the guarantee that subscribers to your published messages will be active. If an orchestration publishes a message for which there are no subscribers then a non-resumable routing failure instance will be raised and a PersistenceException exception will be raised in the orchestration.

I have had some pretty concerned colleagues ask me about the dreaded PersistenceException. This is nothing more than a curiously named exception representing a routing failure. The way I tend to deal with such exceptions in guaranteed delivery scenarios is to create a scope around my send shape (possibly around other close by associated shapes as well) and to catch the PersistenceException (this is in the Microsoft.XLANGS.BaseTypes namespace and it’s assembly is referenced by default in BizTalk Server projects). If the exception is encountered then I raise an alert to administrators (via the ESB portal or relevant exception handling framework) advising of the routing failure, and suspend the orchestration instance. Once the administrators have fixed the problem they can resume the orchestration which will loop back to before the send shape and resend the message.

Single Message

Now of course this pattern comes with a bit more effort in terms of development but one has to ask whether their system can afford to lose a message or at the very least have to go through painful and manual message replay processes.

Another fun scenario I’ve encountered that can go very wrong is taking advantage of direct binding in orchestrations in tandem with a publish subscribe pattern with multiple subscribers to the same message. Say you have an orchestration that sends out a message which is subscribed to by a logging/auditing port and another port which actually performs an important action such as updating a LOB system. If the LOB send port was in an unenlisted state then the message would be directed to your auditing send port, no PersistenceException would be raised in your orchestration and the message would never update the LOB system. So much for guaranteed delivery…

What I would do in this case is create two copies of the same message in the orchestration, each with some sort of instructional context property that is used to direct the message to the relevant send port (the values of this context property being set to abstract values such as “Audit” or “UpdateLOB” rather than the name of the send port since this doesn’t steer away from the concept of loose coupling too far), wrap the send shapes for the two messages in an atomic scope so that only one persistence point is encountered when the messages are sent out (this is a whole other subject but it is important to keep your persistence point and thus your I/Os against your SQL server to a minimum), and wrap the atomic scope with a long running scope which catches a PersistenceException. I then implement the same exception handling pattern I mentioned earlier in this post.

Multiple messages

Once again this comes at a greater effort in development and introduces more overhead on the BizTalk runtime, muddies up your orchestration with logic which is arguably plumbing rather than business logic, and somewhat takes away from how loosely coupled your orchestration is.  That said it does ensure guaranteed delivery.

The exception handling patterns that I’ve discussed here stem from my own cautious nature but I have seen them pay off in multiple instances and have also seen the cost when such thought isn’t applied when required. I wouldn’t say they are required in every orchestration but I would at least encourage developers to think of these scenarios when they decide to what extent they are going to handle exceptions.  At the very least if such patterns aren’t implemented do think about putting a section or at least a blurb in your support documentation to discuss how to recover from such failures.

%d bloggers like this: