Showing posts with label soap fault. Show all posts
Showing posts with label soap fault. Show all posts

Wednesday, April 28, 2010

The way a Weblogic Web Service returns a Stacktrace in a SOAP Fault

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Header />
    <env:Body>
    <env:Fault>
      <faultcode>env:Server</faultcode>
      <faultstring>Failed to invoke end component com.pierre.ws.PierreWS (POJO), operation=generateFault1
-> Failed to invoke method
-> ciao1
</faultstring>
      <detail>
        <bea_fault:stacktrace xmlns:bea_fault="http://www.bea.com/servers/wls70/webservice/fault/1.0.0">java.lang.Exception: ciao1
    at com.pierre.ws.PierreWS.generateFault1(PierreWS.java:18)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at weblogic.wsee.component.pojo.JavaClassComponent.invoke(JavaClassComponent.java:112)
    at weblogic.wsee.ws.dispatch.server.ComponentHandler.handleRequest(ComponentHandler.java:84)
    at weblogic.wsee.handler.HandlerIterator.handleRequest(HandlerIterator.java:141)
    at weblogic.wsee.ws.dispatch.server.ServerDispatcher.dispatch(ServerDispatcher.java:114)
    at weblogic.wsee.ws.WsSkel.invoke(WsSkel.java:80)
    at weblogic.wsee.server.servlet.SoapProcessor.handlePost(SoapProcessor.java:66)
    at weblogic.wsee.server.servlet.SoapProcessor.process(SoapProcessor.java:44)
    at weblogic.wsee.server.servlet.BaseWSServlet$AuthorizedInvoke.run(BaseWSServlet.java:285)
    at weblogic.wsee.server.servlet.BaseWSServlet.service(BaseWSServlet.java:169)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3498)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(Unknown Source)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2180)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2086)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1406)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
</bea_fault:stacktrace>
      </detail>
    </env:Fault>
  </env:Body>
  </env:Envelope>

Tuesday, April 27, 2010

OSB faults transformed into SOAP 1.2 and SOAP 1.1 format

If the client that invokes OSB adheres to the SOAP 1.2 standard, you can always transform the OSB SOAP Fault into the 1.2 standard with this XQuery transformation:


declare namespace xf =
"http://tempuri.org/Transformations/transformations/transformCustomFaultToSoapFault/";
declare namespace soap = "http://www.w3.org/2003/05/soap-envelope";
declare namespace flt = "http://www.bea.com/wli/sb/context";

declare function xf:transformCustomFaultToSoapFault($fault1 as
element(flt:fault))
   as element(soap:Fault) {
       <soap:Fault>
           <soap:Code>
               <soap:Value>soap:Receiver</soap:Value>
           </soap:Code>
           <soap:Reason>
               <soap:Text>{ concat(data($fault1/flt:errorCode) , "-"
, data($fault1/flt:reason)) }</soap:Text>
           </soap:Reason>
           {

               for $location in $fault1/flt:location
               let $node := data($location/flt:node)
               let $pipeline := data($location/flt:pipeline)
               let $stage := data($location/flt:stage)
               let $error-handler := data($location/flt:error-handler)
               let $path := data($location/flt:path)
               return
                   <soap:Node>{ concat($node ,"-" , $pipeline ,"-" ,
$stage ,"-" , $error-handler ,"-" , $path) }</soap:Node>
           }
           {
               for $details in $fault1/flt:details
               return
                   <soap:Detail>{ $details/@* , $details/node() }</soap:Detail>
           }
       </soap:Fault>
};

declare variable $fault1 as element(flt:fault) external;

xf:transformCustomFaultToSoapFault($fault1)

And this is the SOAP 1.1 version:

declare namespace xf =
"http://tempuri.org/Transformations/transformations/transformCustomFaultToSoap11Fault/";
declare namespace ns0 = "http://schemas.xmlsoap.org/soap/envelope/";
declare namespace ns1 = "http://www.bea.com/wli/sb/context";

declare function xf:transformCustomFaultToSoap11Fault($fault1 as
element(ns1:fault))
   as element(*) {
       <ns0:Fault>
       <faultcode>soap:Server</faultcode>
       <faultstring>{ concat($fault1/ns1:errorCode , "-"
,$fault1/ns1:reason) }</faultstring>
       {
       for $node in $fault1/ns1:location/ns1:node
       let  $error-handler := data($fault1/ns1:location/ns1:error-handler)
       let  $path := data($fault1/ns1:location/ns1:path)
       let  $stage := data($fault1/ns1:location/ns1:stage)
       let  $pipeline := data($fault1/ns1:location/ns1:pipeline)
       return
       <faultactor>{ concat($node , "-" , $error-handler , "-" ,
$path , "-" , $stage , "-" , $pipeline) }</faultactor>
       }
       {
       for $details in $fault1/ns1:details
       return
       <detail>{ $details/@* , $details/node() }</detail>
       }
       </ns0:Fault>
};

declare variable $fault1 as element(ns1:fault) external;

xf:transformCustomFaultToSoap11Fault($fault1)

Monday, April 26, 2010

SOAP Fault in OSB

see also http://www.javamonamour.org/2010/07/osb-error-handling-fault.html

this is what the WS method does:

    @WebMethod(action="generateFault1")
    public void generateFault1() throws Exception {
        throw new Exception("ciao1");
    }

and this is what the method generates when run in OSB

    <soapenv:Envelope      xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
    <soapenv:Fault>
    <faultcode>soapenv:Server</faultcode>
    <faultstring>BEA-380001: Internal Server Error</faultstring>
    <detail>
    <con:fault      xmlns:con="http://www.bea.com/wli/sb/context">
    <con:errorCode>BEA-380001</con:errorCode>
    <con:reason>Internal Server Error</con:reason>
    <con:location>
    <con:node>RouteTo_BSPVWS01</con:node>
    <con:path>response-pipeline</con:path>
    </con:location>
    </con:fault>
    </detail>
    </soapenv:Fault>
    </soapenv:Body>
    </soapenv:Envelope>


This is the structure of the fault element




This is how to declare the faults generated by an operation:

http://www.w3.org/TR/wsdl#_soap:fault

here in more details
http://docs.sun.com/app/docs/doc/821-0015/ggeip2?a=view

A really interesting article defining Business Faults versus System Faults, and Fault handling Policies
http://www.troubleshootingwiki.org/Handling_errors_in_SOA_based_systems

nothing new really, in the Java world there are the same concepts, much better defined.


The fascinating thing is that in the Error Handler you have all sort of information disseminated in 2 places: the $fault variable and the $body variable

$fault: <con:fault xmlns:con="http://www.bea.com/wli/sb/context">
  <con:errorCode>BEA-380001</con:errorCode>
  <con:reason>Internal Server Error</con:reason>
  <con:location>
    <con:node>RouteNode1</con:node>
    <con:path>response-pipeline</con:path>
  </con:location>
</con:fault>>

$body: <env:Body xmlns:
env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Fault>
    <faultcode>env:Server</faultcode>
    <faultstring>ciao2</faultstring>
    <detail>
      <java:PierreException xmlns:java="java:com.pierre.exceptions"/>
    </detail>
  </env:Fault>
</env:Body>>

(the exception being thrown is new com.pierre.exceptions.PierreException("ciao2")

The complete stacktrace is missing though...