Custom Error Handling with Oracle Service Bus

An Enterprise Service Bus is becoming a core component in today's Service oriented architectures. Recently, we extended some of our existing services to new clients by integrating those services with service bus. The concepts and terminology of Oracle Service Bus can be found here.

Web Services Client -> Web Services Endpoint

New Interface with Service Bus:

Web Services Client -> Web Services Endpoint

With this new interface, one problem we ran into was that, in case of an exception being thrown by a service, the end client was receiving an Internal BEA error instead of the actual exception being thrown by the service.

The article explains why this happens and provides a solution approach on how meaningful custom messages can be presented to the end SOAP client.

The fundamental reason for this is because of the way, Oracle Service Bus populates its context variables such as $body and $fault when an exception is risen. Details regarding context variables can be found here, but at a high level, when an exception is thrown by the backend service, the exception is put in the $body variable and a predefined System message and error code is put in the $fault variable. The web service client gets a SOAP fault which is populated by the content in $fault and that information is of no help for any troubleshooting.

In order to provide custom error messages to the end client, we implemented the following approach

  • Configure a Service Error Handler for the Proxy
  • Create two proxies one a generic proxy to the business service and another client specific proxy that calls the generic proxy
  • Leverage the Reply with Failure construct that populates $fault with $body

Details regarding the various error codes generated by the service bus are available here. The error codes that are most relevant are:

    Error Code

    Explanation

    BEA-380001

    Service up, but an application exception

    BEA-38002

    Service unavailable

     Other ones

    Service up, but infrastructure related issue


With the above information on hand, in the Service Error Handler of the generic proxy, we used the if-then-else , XQuery functions and raise Error constructs provided by the service bus to throw the appropriate user friendly exception.

  • $fault can be interrogated using fn:starts-with($fault/ctx:errorCode/text(),"BEA-380002")
  • $body can be interrogated for application error using fn:starts-with($body/soap-env:Fault/detail/error/text(),"ServiceProcessor.getData(): Invalid Data Sent ")
  • Raise Error using a custom error code with a custom error message

Thus, in a nutshell, Generic Proxy identifies if it is a System exception or Application exception and rethrows a user friendly exception. The key point is that when a custom exception is thrown from the Generic proxy, $body contains the user friendly message and $fault contains the custom error code.

The client specific proxy, in its service error handler uses the if-then-else construct.

  • interrogates $body using fn:starts-with($body/soap-env:Fault/faultString,"BEA"). If it does, it implies that this is a system error and it raises a user friendly system error
  • Else, it replies with failure.

Service Bus Console

With reply on failure construct, Oracle Service Bus populates $fault with $body and thus enables the web service client to see the actual error message from the SOAP Fault.

Conclusion

    By implementing the approach presented above, readers can customize the error messages to their end SOAP clients and hide the arcane Oracle Service Bus errors.

References