Geeks With Blogs

News View Michael Stephenson's profile on BizTalk Blog Doc View Michael Stephenson's profile on LinkedIn
Michael Stephenson keeping your feet on premise while your heads in the cloud

UPDATE!!!

Following feedback (below) i have revisited this and found that in a small scale POC the default behaviour works fine when returning a fault via a web service.  This however does not yet explain why in the case on our project it did not work.  I am planning to revisit this soon to try and work out why it did not work.  Until then if you have the same problem where the fault doesnt seem to be returned correctly you might want to check out the below as it helped us, and a couple of other people.

 

    Problem

     

    I've seen a few people asking about this one on various forums etc, and unfortunately none of them seem to have an answer which is a bit frustrating, but I think I've actually worked this one out, and hopefully this should make a few people happy :-)

     

    Ok so here is the scenario:

     

  1. BizTalk orchestration published as a web service
  2. Orchestration accessed by a 2 way port
  3. You have added a fault message to the port to return a custom error message
  4. You call the web service the orchestration executes and hits your error condition which causes the fault message to be sent to the port
  5. In HAT you can see the fault message was returned to the port
  6. A soap exception is returned from the web service but no where in it is the custom fault message you threw

     

    The fault message I wished to return is as follows:

     

    ErrorMessage = "Unable to add user to System X. Please contact you Systems Administrator.";

     

    Below is a sample of the soap message returned to my client, the error i get is highlighted in red:

     

       

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

        <soap:Header>

          <wsa:Action>http://schemas.xmlsoap.org/ws/2004/03/addressing/fault</wsa:Action>

          <wsa:MessageID>uuid:03f81957-5a36-4436-ab4e-8aae9488e90b</wsa:MessageID>

          <wsa:RelatesTo>uuid:1fb88687-13af-49bf-be6d-6ead0f27c084</wsa:RelatesTo>

          <wsa:To>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:To>

          <wsse:Security>

            <wsu:Timestamp wsu:Id="Timestamp-92947608-325b-48d0-8ebc-3a703a80dfc0">

              <wsu:Created>2007-05-31T12:36:05Z</wsu:Created>

              <wsu:Expires>2007-05-31T12:41:05Z</wsu:Expires>

            </wsu:Timestamp>

          </wsse:Security>

        </soap:Header>

        <soap:Body>

          <soap:Fault>

            <faultcode>soap:Server</faultcode>

            <faultstring>Failed ---&gt; An exception is thrown by the Orchestration schedule</faultstring>

            <detail />

          </soap:Fault>

        </soap:Body>

      </soap:Envelope>

    No matter what you seem to do you get this "An exception is thrown by the Orchestration schedule" error message.

     

    This one took a bit of fiddling to work out but the solution is below.

     

    Solution

     

    While I was trying to work out what was happening here, I kind of guessed it must be somewhere between the port and the code coming out of the web service where my message was disappearing, I ended up disassembling (with Reflector) the following assembly:

     

    Microsoft.BizTalk.WebServices.ServerProxy.dll

     

    In theServerProxy class there is a method called DeserializeResponseMessage, in here I found the following code snippet:

     

    if (this.respMsgContext.Read(FaultNameProperty.Name.Name, FaultNameProperty.Name.Namespace) != null)

    {

    XmlNode orchestrationErrorMessage = this.GetOrchestrationErrorMessage(response);

    XmlNode detail = new XmlDocument().CreateNode(XmlNodeType.Element, SoapException.DetailElementName.Name, SoapException.DetailElementName.Namespace);

    detail.InnerXml = orchestrationErrorMessage.OuterXml;

    string message = resManager.GetString("OrchestrationOperationFault", CultureInfo.CurrentCulture);

    string text5 = resManager.GetString("OrchestrationDataDump", CultureInfo.CurrentCulture);

    string text6 = message + text5 + detail.OuterXml; TraceLogger.TraceLog.TraceMessage(1, text6);

    throw new SoapException(message, SoapException.ServerFaultCode, base.Context.Request.Url.AbsoluteUri, detail);

    }

     

    I read this to mean that if the FaultName context property is set on the message then this code above will execute and it will create a detail section in the soap fault where it will add my fault message.  Im guessing that this wasn’t being set and therefore it was executing other code which just returns a SoapException without any custom stuff. 

     

    I've never seen any tutorials or documentation on this so I gave it a try.

     

    In the message construct shape where I created the fault message I adjusted the code so it looked like the following snippet:

     

    ErrorMessage = "Unable to add user to System X. Please contact you Systems Administrator.";

    ErrorMessage(BTS.FaultName) = "Fault";

     

    As you can now see I've set the context property.  I think it can be set to anything that isnt null for this to work, but I just set it to "Fault" in this case.

     

    When I reran the original test the soap message I received at the client now looked as follows, my fault message is highlighted in red:

     

     

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

        <soap:Header>

          <wsa:Action>http://schemas.xmlsoap.org/ws/2004/03/addressing/fault</wsa:Action>

          <wsa:MessageID>uuid:aec1480b-c184-4de5-84ee-1032103b7f30</wsa:MessageID>

          <wsa:RelatesTo>uuid:a1f072bd-0c3d-43d8-8412-1d3381355722</wsa:RelatesTo>

          <wsa:To>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:To>

          <wsse:Security>

            <wsu:Timestamp wsu:Id="Timestamp-f802be51-b781-4f6a-a76f-b8aa322d9245">

              <wsu:Created>2007-05-31T12:57:54Z</wsu:Created>

              <wsu:Expires>2007-05-31T13:02:54Z</wsu:Expires>

            </wsu:Timestamp>

          </wsse:Security>

        </soap:Header>

        <soap:Body>

          <soap:Fault>

            <faultcode>soap:Server</faultcode>

            <faultstring>An exception is thrown by the Orchestration schedule</faultstring>

            <faultactor>http://localhost/Acme/IntegrationService.asmx</faultactor>

            <detail>

              <string>Unable to add user to System X. Please contact you Systems Administrator.</string>

            </detail>

          </soap:Fault>

        </soap:Body>

      </soap:Envelope>

     

    The client would still receive the same exception message as before provided by BizTalk, but now if they inspect the detail section of the soap fault they will be able to get access to my error message.

     

    I hope you find this useful and if you have any thoughts or feedback on this please let me know

     

     

     

Posted on Friday, June 1, 2007 3:05 PM BizTalk | Back to top


Comments on this post: BizTalk Web Service does not return fault message

# re: BizTalk Web Service does not return fault message
Requesting Gravatar...
Great !!!
Left by Ajit Jog on Sep 26, 2007 9:07 AM

# re: BizTalk Web Service does not return fault message
Requesting Gravatar...
This is absolutely incorrect to say that BizTalk Web Service does not return fault message . it returns fault message under SoapException.Details.OuterXml. You dont need to do anything on your own. Its the default Biztalk behaviour.

Please Recheck!
Left by Ratnakar Sinha on Oct 05, 2007 12:33 PM

# re: BizTalk Web Service does not return fault message
Requesting Gravatar...
Mike,

You dont need to do even this for sending a fault message. As soon as you pass the fault message using the req-resp port in your orchestration, this property gets populated. You must be definitely missing something .

ITS A DEFAULT BEHAVIOUR OF BIZTALK.

Left by Ratnakar Sinha on Oct 08, 2007 4:45 PM

# re: BizTalk Web Service does not return fault message
Requesting Gravatar...
Ratnakar,

Following your comments i have looked into this again and i can confirm that in a small POC i can get this to work as expected out of the box. Im going to revisit the stuff we did a while back where we had to put in this hack to get it to work and try and find out why in some cases the default behaviour does not work

Thanks
Mike
Left by Mike on Nov 11, 2007 4:01 PM

# re: BizTalk Web Service does not return fault message
Requesting Gravatar...
Thts really nice to hear that it worked. Please send me any further scenarios where u find that its not wrking as it shud.
Left by Ratnakar on Nov 19, 2007 11:48 AM

# re: BizTalk Web Service does not return fault message
Requesting Gravatar...
How do you get this SoapEnvelope from the SoapException?
Which adapter are you using? Soap / Http / or WSE?

I'm using the WSE adapter so perhaps my behavior is different to what you are describing above.
Left by Ryan CrawCour on Nov 22, 2007 7:10 AM

Your comment:
 (will show your gravatar)


Copyright © Michael Stephenson | Powered by: GeeksWithBlogs.net