2
votes

I've recently switched from Mule 2.2.1 to Mule 3.x

The gist of this is Mule 3 does not return stacktrace but Mule 2 does, how do i replicate the Mule 2 behavior?

More details:

Some of the web services are wrapped in a try-catch where we throw a ServiceException

@WebFault(name = "ServiceException")
    public class ServiceException extends Exception {
    private static final long serialVersionUID = 1L;
    private Integer errorNumber;

public ServiceException(Exception e, User user) {
    super(makeMessage(e));
    LoggingDao.logException(this.getMessage(), e.toString());
    this.setStackTrace(e.getStackTrace());
    this.errorNumber = LoggingDao.getLogId();
} ... etc

Where we catch the exception with the goal of returning the stacktrace to the web service caller, by the way the LoggingDao logs the stacktrace but the web service doesn't return it.

Somewhere along the road we jump into DefaultComponentLifecycleAdapter.java which throws a MuleException which overrides the stacktrace and returns

  <soap:Fault>
     <faultcode>soap:Server</faultcode>
     <faultstring>Component that caused exception is: org.mule.component.DefaultJavaComponent component for: SedaService{...}. Message payload is of type: Object[]</faultstring>
  </soap:Fault>

How would i go about returning the stacktrace in Mule 3.x

P.S. I am using Mule 3.0.1 which doesn't seem to be compatible with the link i provided above.

also from: http://www.mulesoft.org/documentation/display/MULE3USER/Error+Handling

If the flow exchange-pattern is request-response, a different message is returned to the caller after has been executed. The message has org.mule.transport.NullPayload as its payload and the exceptionPayload attribute is set to the following: org.mule.api.ExceptionPayload .< Is the aforementioned what's giving me trouble?

from mule 2 mule-config.xml is different in regards to that the exchange-pattern is not "request-response"

1

1 Answers

2
votes

I've been told that this is a known problem in Mule 3.x < 3.2 The solution is to write an OutFault Interceptor code by
Tomas Blohm

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

public CustomSoapFaultOutInterceptor() {
        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);
    //delete the Mule Exception to have the one throw by the component in the SoapMessage
        Throwable t = getOriginalCause(fault.getCause());
        fault.setMessage(t.getMessage());
    }
    private Throwable getOriginalCause(Throwable t) {
        if (t.getCause() == null || t.getCause().equals(t))
            return t;
        else
            return getOriginalCause(t.getCause());
    }
}

//And then this into mule-config.
<cxf:jaxws-service>
   <cxf:outFaultInterceptors>
      <spring:bean class="is.tr.mule.interceptor.CustomSoapFaultOutInterceptor"/>
   </cxf:outFaultInterceptors>
</cxf:jaxws-service>