Service Bus 12c – Error Handling

In this post, you will learn to do Error Handling and will incorporate in the Pipeline Template created in post.  We consider our Pipeline to return generic Fault response with error message in all possible error scenarios.

As you know, service provider can send error to consumer in following ways:

  • As a normal response, by populating fields like “ErrorNumber” and “ErrorMesssage” (assuming that these fields are defined in response message of operation in WSDL).
  • As a SOAP fault

Typically when Service Bus is mediating, you might have to transform Error or Fault response to the Fault structure defined in WSDL. For this, you need to understand Message Context Variables that can be used.

As per WS-I BP, the service provider should send the HTTP response code as 200 when the error is sent as normal response and 500 should be sent when the error is sent as SOAP fault.

In message flow, Error Handler can be defined for Stage node, Pipeline Pair node (both Request Pipeline and Response Pipeline individually), Routing node and for entire Pipeline (called Service Error Handler). When HTTP response code 200 is received, Service Bus treats it as a normal response and proceeds further with message flow. When response code 500 is received, Service Bus runtime control goes to Service Error Handler if it exists or any other low level Error Handlers depending on where you received. That means Service Bus treats even Fault response as normal response when HTTP response code is 200.

Service Bus populates different message context variables with error/fault messages and is accessible in Error Handler depending on whether you used Routing or Service Callout. The following table summarizes this discussion:

Activity

Scenario

Context Variable

Routing

Raise Error activity

$fault

Routing

Fault Response from business service

$body

Routing

System fault while calling business service

$fault

Service Callout

Raise Error activity

$fault

Service Callout

Fault Response from business service

$fault

Service Callout

System fault while calling business service

$fault

So there is a possibility of 3 context variables $body, $fault and $faultVar having Error or Fault information (assuming faultVar is variable used in Raise Error activity of your message flow).

With this background, let us get back to Pipeline Template to add required Error Handler. Since your Pipeline uses both Service Callout and Routing in message flow, you can do fault handling in the following manner in Pipeline Template so that all of your concrete pipelines using this template would inherit this automatically.

  • Add Service Error Handler.
  • Add conditional branches in error handler to verify $body is populated with SOAP Fault, or faultVar or $fault is populated. Based on this, you have to extract Error Code and Error Message from $body, $faultVar and $fault variables.
  • Populate $body variable with the Fault structure as defined in WSDL.
 
Changes in CustomerPipelineTemplate:

Drag If-Then activity into ErrorHandler stage from Flow Control and add 3 conditional branches (Else If branch) as shown below.

clip_image002

In Properties tab, set Condition for all branches in Expression Builder as shown below. Remember adding the namespace http://www.bea.com/wli/sb/stages/transform/config with con1 as alias in Namespaces.

Branch

Condition

Purpose

If

not(fn:empty($body/soap-env:Fault))

To handle fault received in Routing.

Else If

not(fn:empty($faultVar))

To handle error response from given in Raise Error activity.

Else If

not(fn:empty($fault/ctx:details/con1:ReceivedFaultDetail))

To handle fault received in Service Callout or Raise Error cases.

Else

-NA-

All other cases.

Drag Replace activity from Message Processing into each of these branches and set properties as shown below.

clip_image003

Set expression in Expression Builder with following SOAP Fault structure for Replace activity in If branch. Here you are extracting Error Code and Error Message from received SOAP fault received in Routing. This way you are forwarding the actual error from Service Provider to Consumer.

<soap-env:Fault>

<faultcode>env:Server</faultcode>

<faultstring>{$body/soap-env:Fault/faultstring/text()}</faultstring>

<detail>

<cust:ErrorStatusMsg xmlns:cust="http://xmlns.xyzbank.com/schema/Customer"&gt;

<ErrorCode>{$body/soap-env:Fault/faultcode/text()}</ErrorCode>

<ErrorMsg>{$body/soap-env:Fault/faultstring/text()}</ErrorMsg>

</cust:ErrorStatusMsg>

</detail>

</soap-env:Fault>

Set expression in Expression Builder with following SOAP Fault structure for Replace activity in Else If branch. Here you are extracting Error Code and Error Message used in Raise Error activity. Observe the usage of $fault variable to get error code given in RaiseError activity. This way you are forwarding the error message used in Raise Error activity to Consumer.

<soap-env:Fault>

<faultcode>env:Server</faultcode>

<faultstring>{$faultVar/error_message/text()}</faultstring>

<detail>

<cust:ErrorStatusMsg xmlns:cust="http://xmlns.xyzbank.com/schema/Customer"&gt;

<ErrorCode>{$fault/ctx:errorCode/text()}</ErrorCode>

<ErrorMsg>{$faultVar/error_message/text()}</ErrorMsg>

</cust:ErrorStatusMsg>

</detail>

</soap-env:Fault>

Set expression in Expression Builder with following SOAP Fault structure for Replace activity in second Else If branch. Here you are extracting Error Code and Error Message from SOAP Fault received in Service Callout. This way you are forwarding actual error from Service Provider to Consumer.

<soap-env:Fault>

<faultcode>env:Server</faultcode>

<faultstring>{$fault/ctx:reason/text()}</faultstring>

<detail>

<cust:ErrorStatusMsg xmlns:cust="http://xmlns.xyzbank.com/schema/Customer"&gt;

<ErrorCode>{$fault/ctx:details/con1:ReceivedFaultDetail/con1:faultcode/text()}</ErrorCode>

<ErrorMsg>{$fault/ctx:details/con1:ReceivedFaultDetail/con1:faultstring/text()}</ErrorMsg>

</cust:ErrorStatusMsg>

</detail>

</soap-env:Fault>

Set expression in Expression Builder with following SOAP fault structure for Replace activity in Else branch. Here you are extracting Error Code and Error Message from $fault to take care of other possible error scenarios.

<soap-env:Fault>

<faultcode>env:Server</faultcode>

<faultstring>{$fault/ctx:reason/text()}</faultstring>

<detail>

<cust:ErrorStatusMsg xmlns:cust="http://xmlns.xyzbank.com/schema/Customer"&gt;

<ErrorCode>{$fault/ctx:errorCode/text()}</ErrorCode>

<ErrorMsg>{$fault/ctx:reason/text()}</ErrorMsg>

</cust:ErrorStatusMsg>

</detail>

</soap-env:Fault>

Now drag Reply activity into ErrorHandler stage from Flow Control after If-then. In Properties tab, select property as With Failure. This would send HTTP response code as 500 along with SOAP fault. Selecting With Success will send HTTP response code as 200.

clip_image005

Alternatively, you can come up with a XQuery map accepting these parameters and return appropriate SOAP fault structure. Now your ErrorHandler stage should look like below.

clip_image007

Observe that the Proxy Service you created using this Pipeline Template in this post had inherited ErrorHandler stage as shown below.

clip_image009

Some times, you may want to give your specific messages or override the messages from Service Provider. You can make all this kind of changes in your Error Handler and also typically one would want to convert System Errors into generic Application Error before sending to Proxy Service consumer. You can find more about details element in $fault variable here.

Testing:

Run your Pipeline and observe Flow Trace and Variables as shown below. Observe that the Error response from your Pipeline always contains a SOAP Fault conforming to WSDL.

Following are a few of the screenshots showing different Fault responses for both Routing and Service Callout in different error scenarios.

System Error in Routing:

clip_image013

Error Response received in Routing:

clip_image015

Fault Response received in Routing:

clip_image017

Validate activity failure Error:

clip_image019

System Error received in Service Callout:

clip_image023

Error Response received in Service Callout:

clip_image024

Fault Response received in Service Callout:

clip_image026

15 Responses to “Service Bus 12c – Error Handling”


  1. 1 Rohit Kritika Agarwal September 15, 2020 at 3:28 PM

    Hi Siva,

    how we can handle the business Error Response, if the response code is other than http 200- http 207.

    i am calling a Rest application where the response is coming in json format,

    i have tried both body and fault variable but can’t see the actual Error Response

  2. 2 Anonymous August 10, 2018 at 3:29 AM

    Hi Siva,

    I’m invoking a REST service from an OSB Proxy Service, which is working fine if the rest service response is a valid response, i.e., there’s no errors. However if the rest service replies with an http error code (e.g. 400 Bad Request), I’m not able to capture anything else except the http error code:

    $fault variable in OSB:

    BEA-382502

    OSB Service Callout action received an error response

    400

    PipelinePairNode1
    PipelinePairNode1_request
    stage1
    request-pipeline

    But the rest service, is not only replying with 400 Bad Request, but also adding a message:

    The message header contains an invalid brand code.

    Which I’m not able to process in my proxy service. Does anyone knows if it is possible to access this message details in OSB or is it a limitation?

    The rest service is clearly sending the message, because invoking it directly through Postman I’ll get the following response:

    The message header contains an invalid brand code.

    I am trying to capture this message and i am able to capture the error and not the Message

  3. 4 Kenny January 18, 2018 at 9:42 PM

    Hi svgonugu, thanks for this excelent errorhandler. But what if you could also get non-soapfault messages with HTTP 500? Am i wrong to assume this is possible and if not how could you catch these cases?

    • 5 svgonugu January 19, 2018 at 9:25 AM

      If the business service is wsdl based whatever the error we get it should wrapped in a soap fault and return it to proxy…details tag in $fault should ha e this information

  4. 6 sridhar November 17, 2017 at 4:38 PM

    Dear Siva,

    thanks for your post, in case of Routing Fault occurred due to fault response from provider, in that case can you please post how to retrieve the fault location an path using body context variable as fault variable populated in Body.

    thanks,Sridhar G

  5. 7 Alberto Martin Moreno October 30, 2017 at 8:59 PM

    One questio:, this only works if your body is soap 1.2 because if you are using soap 1.1 your Fault structure is not correct, isn’t?

  6. 9 Wellington December 15, 2016 at 12:44 AM

    Hi Shiva,

    The $faultVar variable still exists in OSB 12c ? I didn’t find it in this version.

    Thanks!

    • 10 svgonugu December 15, 2016 at 9:30 AM

      It’s $fault…$faultVar is own variable name..

      • 11 Kenny January 18, 2018 at 9:23 PM

        Does this mean the second ‘if’ (checking if $faultVar is not empty) should be checking if $fault is empty?

        I tried doing this but then the xpaths are no longer correct as “error_message” does not exist in my $fault.

        So i changed it to ‘$fault/ctx:reason/text()’ since the message seems to be contained in the ‘reason’ element. But then we have exactly the same as the else branch so it seems useless to check wether the $fault is fill in?

  7. 12 VIjay Kumar December 13, 2016 at 1:00 PM

    Dear Shiva,

    Thank you for your post . I have started to follow you post . I need WSDL and XSD for all of your demo POC . It will be great if you can share the downloadable link.


  1. 1 Service Bus 12c – Series of Articles by Siva | SOA Community Blog Trackback on February 19, 2015 at 12:20 PM
  2. 2 Service Bus 12c – Series of Articles | Siva's Blog Trackback on October 30, 2014 at 1:33 PM

Leave a reply to svgonugu Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.




Pages

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 379 other subscribers

Enter your email address to follow this blog and receive notifications of new posts by email.