]> Catching WCF Faults in BizTalk Orchestrations 🌐:aligrant.com

Catching WCF Faults in BizTalk Orchestrations

Alastair Grant | Fri 20 Jan 2012

Whether WCF is actually good or not is a debate for another day, the simple fact is with BizTalk it's replaced the SOAP adapter - and does bring some flexibility in making things loose.

When it comes to Fault messages though it's a bit... naff. When consuming a WCF service in BizTalk you are likely to get a Fault operation with a Message Direction of Fault. But it doesn't matter what you do, there doesn't appear to be a way of attaching a receive shape to it.

Instead you have to use an Exception handler to catch the fault. The Exception type will be generated when you consumed the service, so it will be available in the Exception Object Type drop down. The SOAP Fault will still be an XML message and you treat the object as a multi-part message. It will most likely be document based so you'll either have to find the generated fault schema and promote the properties you're interested in; or use the xpath() function to pull out the data.

This is though, was only the beginning. As it's WCF you have to setup the Send Port correctly. Assuming you've already cottoned onto having to put the SOAP action into the send port instead of it working it out automatically (thank you one port for each damn action)... we now have to configure how the SOAP message is handled.

On the Messages tab we have the ability to "Propagate fault message". This essentially translates to "send fault message through to the Orchestration".

If you don't have it enabled then the adapter will throw an Exception and will suspend the Send message instance. If you're using a one-way send this might be handy if you want to resume from here. As most web-services have at least a response to confirm receipt you'll likely to already have soft-error handling in your Orchestration. HAT will record this as a transmission failure, with the fault message content as the exception.

If you enable propagation then the adapter won't view a fault as an exception, so won't suspend the message instance, and instead return it as a message to your Orchestration. This generally results in much tears as it's an unexpected message. And your nice exception handler catering for the fault completely fails to catch.

As a SOAP:Fault node is a child of SOAP:Body and not an alternative you will receive the SOAP:Fault as a root element and not the content of it. Pain in the arse. In order to avoid this you need to customise the Inbound BizTalk message body with the "Path" option. Use a Body path expression of:

/*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/' and local-name()='Fault']/detail/* | /*[not(namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/')]

This XPath will return anything that is not a SOAP component (i.e. your normal message body that you'd expect 99% of the time), OR the child of the detail node of a SOAP:Fault message.

BizTalk can now recognise the SOAP Fault and your exception handler will now catch it.
 

Breaking from the voyeuristic norms of the Internet, any comments can be made in private by contacting me.

Related