Announcement Announcement Module
Collapse
No announcement yet.
MessageHandlingException does not propagate Spring WS custom Soap fault errors Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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, 08:56 PM.

  • #2
    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

    Comment


    • #3
      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, 02:09 PM.

      Comment


      • #4
        Jira issue created. http://jira.springframework.org/browse/INT-993

        Comment


        • #5
          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

          Comment


          • #6
            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.

            Comment


            • #7
              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?

              Comment


              • #8
                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

                Comment

                Working...
                X