Results 1 to 8 of 8

Thread: MessageHandlingException does not propagate Spring WS custom Soap fault errors

  1. #1
    Join Date
    Apr 2005
    Posts
    112

    Default MessageHandlingException does not propagate Spring WS custom Soap fault errors

    Expected Result:

    Code:
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
       <SOAP-ENV:Header/>
       <SOAP-ENV:Body>
          <SOAP-ENV:Fault>
             <faultcode>SOAP-ENV:Client</faultcode>
             <faultstring xml:lang="en">Invalid Client Id.</faultstring>
          </SOAP-ENV:Fault>
       </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    The actual error received:
    Code:
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
       <SOAP-ENV:Header/>
       <SOAP-ENV:Body>
          <SOAP-ENV:Fault>
             <faultcode>SOAP-ENV:Server</faultcode>
             <faultstring xml:lang="en">method 'public gov.dc.dmv.destiny.eis.services.ext.dcivs.domain.IvsResponse gov.dc.dmv.destiny.eis.services.ivs.service.impl.IvsServiceImpl.getInsuranceVerificationData(gov.dc.dmv.destiny.eis.services.ext.dcivs.domain.IvsRequest) throws gov.dc.dmv.destiny.eis.services.common.exception.InvalidDataException,gov.dc.dmv.destiny.eis.services.common.exception.InvalidRegionException,javax.xml.datatype.DatatypeConfigurationException,gov.dc.dmv.destiny.eis.services.common.exception.NoDataAvailableException' threw an Exception.</faultstring>
          </SOAP-ENV:Fault>
       </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    Exception Message:

    Code:
    org.springframework.integration.message.MessageHandlingException: method 'public gov.dc.dmv.destiny.eis.services.ext.dcivs.domain.IvsResponse gov.dc.dmv.destiny.eis.services.ivs.service.impl.IvsServiceImpl.getInsuranceVerificationData(gov.dc.dmv.destiny.eis.services.ext.dcivs.domain.IvsRequest) throws gov.dc.dmv.destiny.eis.services.common.exception.InvalidDataException,gov.dc.dmv.destiny.eis.services.common.exception.InvalidRegionException,javax.xml.datatype.DatatypeConfigurationException,gov.dc.dmv.destiny.eis.services.common.exception.NoDataAvailableException' threw an Exception.	
    Caused by: gov.dc.dmv.destiny.eis.services.common.exception.InvalidDataException: Invalid Client Id
    	at gov.dc.dmv.destiny.eis.services.common.aop.EisServiceClientIdValidator.before(EisServiceClientIdValidator.java:83)
    I have Spring Integration MarshallingWebServiceInboundGateway as the Webservices inbound endpoint gateway. It then sends the request to Transformer and then to Service Activator. The service activator has an AOP interceptor and checks for a valid client id in the request message. If there is none, it throws "Invalid Client Id" normal Soap fault error with fault code as CLIENT. The channels configured are all direct channels since the invocation is synchronous.

    Soap Fault Exception:
    Code:
    package gov.dc.dmv.destiny.eis.services.common.exception;
    
    import org.springframework.ws.soap.server.endpoint.annotation.FaultCode;
    import org.springframework.ws.soap.server.endpoint.annotation.SoapFault;
    
    /**
     * InvalidDataException.java : Exception thrown when some of the required
     * data as per the conditional business logic is not present in the inbound 
     * request message. 
     * @author Vigil Bose 
     */
    @SoapFault(faultCode = FaultCode.CLIENT)
    public class InvalidDataException extends Exception {
    
    	private static final long serialVersionUID = 1L;
    
    	public InvalidDataException(String message){
    		super(message);
    	}
    	
    }
    Any idea why I do not see the expected soap fault behavior. If I do not use MarshallingWebServiceInboundGateway and use simple gateway interface with the appropriate throws clause in the method signature, I see the expected behavior. MarshallingWebServiceInboundGateway is the ideal choice since it eliminates a simple Gateway interface, and two other classes. Any insight would be highly helpful.

    Thanks,
    Vigil
    Last edited by vbose; Feb 6th, 2010 at 07:56 PM.

  2. #2
    Join Date
    May 2007
    Location
    Netherlands
    Posts
    614

    Default

    Your problem is caused by SimpleMessagingGateway:
    Code:
    	@Override
    	protected Object fromMessage(Message<?> message) {
    		try {
    			return this.outboundMapper.fromMessage(message);
    		}
    		catch (Exception e) {
    			if (e instanceof RuntimeException) {
    				throw (RuntimeException) e;
    			}
    			throw new MessagingException(message, e);
    		}
    	}
    If you make InvalidDataException extend RuntimeException your problem should go away. The quoted piece of code might not be correct, but if you want to argue that you should create and issue for it

  3. #3
    Join Date
    Apr 2005
    Posts
    112

    Default

    I tried changing the InvalidDataException to extend from RuntimeException without any luck. The error is given below.

    Code:
    org.springframework.integration.message.MessageHandlingException: error occurred in message handler [ServiceActivator for [org.springframework.integration.handler.MessageMappingMethodInvoker@1bca486]]
    	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:65)
    ....
    
    Caused by: gov.dc.dmv.destiny.eis.services.common.exception.InvalidDataException: Invalid Client Id
    	at gov.dc.dmv.destiny.eis.services.common.aop.EisServiceClientIdValidator.before(EisServiceClientIdValidator.java:83)
    Soap Error:

    Code:
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
       <SOAP-ENV:Header/>
       <SOAP-ENV:Body>
          <SOAP-ENV:Fault>
             <faultcode>SOAP-ENV:Server</faultcode>
             <faultstring xml:lang="en">error occurred in message handler [ServiceActivator for [org.springframework.integration.handler.MessageMappingMethodInvoker@1bca486]]</faultstring>
          </SOAP-ENV:Fault>
       </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    Refactored InvalidDataException.java
    Code:
    import org.springframework.ws.soap.server.endpoint.annotation.FaultCode;
    import org.springframework.ws.soap.server.endpoint.annotation.SoapFault;
    
    /**
     * InvalidDataException.java : Exception thrown when some of the required
     * data as per the conditional business logic is not present in the inbound 
     * request message. 
     * @author Vigil Bose 
     */
    @SoapFault(faultCode = FaultCode.CLIENT)
    public class InvalidDataException extends RuntimeException {
    
    	private static final long serialVersionUID = 1L;
    
    	public InvalidDataException(String message){
    		super(message);
    	}
    	
    }
    Last edited by vbose; Feb 23rd, 2010 at 01:09 PM.

  4. #4
    Join Date
    Apr 2005
    Posts
    112

  5. #5
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    The AbstractMessageHandler is catching any Exception (including RuntimeExceptions) and then wrapping in MessagingException. So, your exception is the root-cause but not the actual type of the Exception being thrown by the endpoint.

    We might want to unwrap the Exception in the marshalling gateway and rethrow it (if the cause is a RuntimeException). However, I am wondering why this behavior would be different for the SimpleWebServiceInboundGateway as you mentioned. Do you have any more information to add?

    Thanks,
    Mark

  6. #6
    Join Date
    Oct 2009
    Posts
    21

    Default

    Quote Originally Posted by Mark Fisher View Post
    The AbstractMessageHandler is catching any Exception (including RuntimeExceptions) and then wrapping in MessagingException. So, your exception is the root-cause but not the actual type of the Exception being thrown by the endpoint.

    We might want to unwrap the Exception in the marshalling gateway and rethrow it (if the cause is a RuntimeException). However, I am wondering why this behavior would be different for the SimpleWebServiceInboundGateway as you mentioned. Do you have any more information to add?

    Thanks,
    Mark
    Is there a reason why exceptions are wrapped in a MessagingException if they are of type RuntimeException?

    I wanted to convert a class to use spring integration but i ended up introducing bugs because the existing exception handling no longer worked.

  7. #7
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    The reason we are wrapping even RuntimeExceptions is that we want to provide a common type for any exception that occurs during the message flow. Sharing a hierarchy with a single common base type (MessagingException) simplifies any code that does want to catch those explicitly. However, I can also see the rationale behind letting RuntimeExceptions propagate as-is (we do that at lower levels). Would the un-wrapping at the Gateway proxy itself as I mentioned above be sufficient for your case?

  8. #8
    Join Date
    Oct 2009
    Posts
    21

    Default

    Quote Originally Posted by Mark Fisher View Post
    The reason we are wrapping even RuntimeExceptions is that we want to provide a common type for any exception that occurs during the message flow. Sharing a hierarchy with a single common base type (MessagingException) simplifies any code that does want to catch those explicitly. However, I can also see the rationale behind letting RuntimeExceptions propagate as-is (we do that at lower levels). Would the un-wrapping at the Gateway proxy itself as I mentioned above be sufficient for your case?
    Yes - unwrapping it at the gateway proxy would resolve the issue

    Thx for the quick response

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •