Orchestration - Handle SOAP Exception and deal with Suspended (resumable) messages

Posted at: 5/16/2007 at 6:52 PM by saravana

The main reason for this blog post is due to this newsgroup post

Download Sample from here.

Step #1: Catching SOAP Exception:

Whenever you call a Web service it's a good practice to handle the SOAP exception specifically rather than just leaving the orchestration to throw an un-handled exception which will result in orchestration service instance and all the referenced message instances being suspended. As shown in the following Orchestration diagram, handling a  SOAP exception is straight forward. Place your "Send" shape inside a "Scope" and add an Exception Handler with "Exception Object Type" configured to System.Web.Services.Protocols.SoapException (You need to add reference to "System.Web.Services"). The "Message Assignment" shape  inside the catch block got this simple statement

SOAP_EXCEPTION_MESSAGE = soapException.Detail.InnerXml;

Where SOAP_EXCEPTION_MESSAGE is an Orchestration message of type System.String and soapException is the "Exception object name" we assigned for the exception handler. So, with the following setup, whenever there is an exception a message similar to the one shown below will be generated and send across the wire with configured adapter (FILE, SMTP etc).

<string><ns0:NACK Type="NACK" xmlns:ns0="http://schema.microsoft.com/BizTalk/2003/NACKMessage.xsd"><NAckID>{2DA185D7-40E7-4279-9F6E-ADCEB6EF599B}</NAckID><ErrorCode>0xc0c01f07</ErrorCode><ErrorCategory>0</ErrorCategory><ErrorDescription>SoapException: System.Web.Services.Protocols.SoapException: Purposely raised this exception for testing at CustomerProcessing.Get500InternalSoapException(String yourName) </ErrorDescription></ns0:NACK></string>

Step #2: suspended(resumable) messages:

Even though you handled the SOAP exception using an exception handler in STEP #1, it's only going to complete the orchestration gracefully but it's going to leave the original request message you posted to the web services in a suspended(resumable) state. Bear in mind the SOAP exception will be raised inside the orchestration only after the send port has exhausted all the retries.  During this period the messaging instance and orchestration service instance will be in the dehydrated state as shown below.

After all the retries, the SOAP exception will be raised inside the orchestration and corresponding SOAP request message will be suspended with resumable state as shown below. This will help the administrator to either resume or terminate the message later.

 

But at some scenario we don't wont to leave the suspended (resumable) messages in the messagebox, instead move them to a different location (either to file system location or a remote server via HTTP etc, etc). Before BizTalk 2006 the only way to archive this behavior is by writing some WMI scripts, which is OK but doesn't really fit with the message flow infrastructure. But with BizTalk 2006 we can take advantage of "Failed Message routing" capability and make this task seamless.

All you have to do is, on your SOAP send port check the check box "Enable routing for failed messages" (as shown in the following figure) and also you can set optionally the "Retry Count" value to "0" if you want to raise the SOAP exception straight away.

Then configure a "Send Port"  (or an orchestration, if you want to do more business logic with the suspended messages) with following filter condition

ErrorReport.ErrorType == "FailedMessage"

ErrorReport.OutboundTransportLocation ==  http://localhost:47653/SOAPExceptionHandler.WebService/CustomerProcessing.asmx

The above filter condition will make sure you are dealing only with SOAP exception raised due to messages posted to that particular web service (CustomerProcessing.asmx). There are quite a bit of promoted properties that comes along with "ErrorReport" you can take advantage of to cater your situation as listed below.

  • Description
  • ErrorType
  • FailureCategory
  • FailureCode
  • InboundTransportLocation
  • MessageType
  • OutboundTransportLocation
  • ReceivePortName
  • RoutingFailureReportID
  • SendPortName

Related Reading:

http://blogs.conchango.com/matthall/archive/2005/07/28/1894.aspx

http://objectsharp.com/cs/blogs/matt/archive/2006/11/01/4110.aspx

Nandri!

Saravana 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: | | |  Categories: BizTalk General
Actions: Email this article Email | Kick it! | DZone it! | Save to del.icio.us | Technorati Links
Post Information: Permanent LinkPermalink | CommentsComments(3) | Comments RSS

Comments

Thursday, May 24, 2007 10:11 PM
Anonymous
Anonymous
I have a similar scenario except that I have exposed my orchestration as web service and I want to catch the exception from called web service, construct a fault message and send it back to my orchestrations receive response port exposed as web service. In this case the call to the orchestration web service always timesout and the fault message gets suspended. Do you have any other ideas.
Friday, June 15, 2007 2:06 PM
Anonymous
Anonymous
I have had the same problem. This describe my problem.

My Scenario:
I have published a schema as a web service. The orchestration that will handle an incoming message will in turn send a message to a web service and eventually return a response message back to the caller. If an exception occurs on the send port I want to be able to catch it and return a response containing information about the failure.

My Symptoms:
BizTalk will suspend my orchestration and also produce a routing failure, causing the calling web service to time-out.

“A response message for two-way receive port "<myPortName>" is being suspended as the messaging engine could not correlate the response to an existing request message. This usually happens when the host process has been recycled”

The routing failure is caused by a PersistenceException thrown by the XLANG engine and information about the error was found in the event log.

“The published message could not be routed because no subscribers were found.”

with the following additional information:

“Failed to publish (send) a message in the batch. This is usually because there is no one expecting to receive this message. The error was The published message could not be routed because no subscribers were found.”

The Solution:
This behavior actually seems to be a bug in BizTalk. After a bit of research I came across this hot fix: support.microsoft.com/default.aspx" rel="nofollow">support.microsoft.com/default.aspx" REL="nofollow">support.microsoft.com/default.aspx" rel="nofollow">support.microsoft.com/default.aspx. The hot fix corrects an error in the ‘Btsmsgcore.dll’ for two-way SQL Adapters but it fixed my problem with the two-way SOAP adapter to.

Note:
The hot fix will only eliminate the routing failure. The orchestration will still be suspended in the message box after the response has been returned. This will need to be handled through enabling routing for failed messages.
Tuesday, July 10, 2007 7:26 PM
Himanshu Zinzuwadia
Thanks. This worked for me.

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading