Nitin Gaur
Nitin Gaur

Reputation: 1136

Setting SOAP fault in Mule

Currently this is how I'm catching exception and setting the payload

<catch-exception-strategy name="Catch_Exception_Strategy">
   <logger message="#[exception.summaryMessage]" level="ERROR" doc:name="Logger"/>
   <set-payload value="Error in service operation" doc:name="Set Payload"/>
</catch-exception-strategy>

But, CXF SOAP component sets the payload of real response object. While I want to send an error object in a SOAP Fault instead. How can I do that?

Thanks in advance.

Update

Default exception strategy sends SOAP Fault with error message. Initially my purpose was to just add the logger and let the default error message go in the SOAP Fault. I added Catch exception strategy but later found out it does not send SOAP fault. Instead then I used Rollback strategy that send SOAP fault. However, there was not much benefit of logging exception inside strategy block using Mule Logger as it is already logged by Mule.

Now, I realize the advantage of using cxf:outFaultInterceptor. You can not only add custom elements to SOAP Fault but you can also segregate custom logs in separate log file. Thanks Anirban for providing sample interceptor class.

Upvotes: 0

Views: 3774

Answers (1)

Anirban Sen Chowdhary
Anirban Sen Chowdhary

Reputation: 8321

There are many ways to do it.. One of the way is using a expression component in Catch block like the following :-

<catch-exception-strategy doc:name="Catch Exception Strategy">
  <set-variable variableName="id" value="Invalid Request !!!" doc:name="Variable"/>
  <expression-transformer expression="#[message.payload=&quot;&lt;soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'&gt;\n  
   &lt;soap:Body&gt;\n      &lt;soap:Fault&gt;\n      &lt;faultcode&gt;INVALID_REQUEST&lt;/faultcode&gt;\n      &lt;faultstring&gt;Invalid Request&lt;/faultstring&gt;\n      &lt;detail&gt;\n      &lt;ns4:Fault xmlns='http://services.test.com/schema/report/SendReport' xmlns:ns4='http://services.test.com/schema/common/Fault'&gt;\n      &lt;ns4:errCode&gt;-2&lt;/ns4:errCode&gt;\n      &lt;ns4:errorDesc&gt;System Fault&lt;/ns4:errorDesc&gt;\n      &lt;ns4:stackTrace&gt;Invalid Request.Please  ensure that you use the correct request header as per the schema&lt;/ns4:stackTrace&gt;\n      &lt;/ns4:Fault&gt;\n      &lt;/detail&gt;\n      &lt;/soap:Fault&gt;\n     &lt;/soap:Body&gt;\n    &lt;/soap:Envelope&gt;&quot;]" doc:name="Expression_Custom_Fault_Response"/>
  </catch-exception-strategy>

Other way is to use Custom Java class in CXF fault interceptor :-

<cxf:jaxws-service service="MainData" serviceClass="Your Service class"  doc:name="SOAPWithHeader" >
<cxf:outFaultInterceptors>  
<spring:bean id="outfault" class="Your custom fault interceptor Java Class"/>
</cxf:outFaultInterceptors>
</cxf:jaxws-service>

UPDATED ANSWER

Customise the fault interceptor class :-

public class CustomSoapFault extends AbstractSoapInterceptor
 {
            private static final Log logger = LogFactory.getLog(CustomSoapFaultOutInterceptor.class);

        public CustomSoapFault() 
             {
                super(Phase.MARSHAL);
                getAfter().add(Soap11FaultOutInterceptor.class.getName());
             }
            @Override
            public void handleMessage(SoapMessage message) throws Fault
             {
                Fault fault = (Fault) message.getContent(Exception.class);
                logger.error(fault.getMessage(), fault);
            //custom message in response
     Element detail = fault.getOrCreateDetail();
                Element errorDetail = detail.getOwnerDocument().createElement("error-reply");
                Element error = errorDetail.getOwnerDocument().createElement("error");
                Element extRefNumber = errorDetail.getOwnerDocument().createElement("ExternalReferenceNumber");
                Element partnerId = errorDetail.getOwnerDocument().createElement("PartnerID");

                partnerId.setTextContent("123");
                extRefNumber.setTextContent("321");
                error.setTextContent("Contact the administrator");

                errorDetail.appendChild(error);
                errorDetail.appendChild(extRefNumber);
                errorDetail.appendChild(partnerId);
                detail.appendChild(errorDetail);
              }

  }

//Provide the class in CXF interceptor

<cxf:jaxws-service>
   <cxf:outFaultInterceptors>
      <spring:bean class="com.mypackage.mule.interceptor.CustomSoapFault"/>
   </cxf:outFaultInterceptors>
</cxf:jaxws-service>

Upvotes: 2

Related Questions