Results 1 to 8 of 8

Thread: Error handling in direct channels

  1. #1
    Join Date
    Jul 2008
    Posts
    21

    Default Error handling in direct channels

    My message flow goes from a JMS listener to service activators going through unmarshaller transformer, splitter and routers. Everything is synchronous.

    What is the best way to handler errors in unmarshalling, service activator, etc ? I would like have both message and runtime exception to log the problem or at least process it differently than normal.

    How should I handle errors?
    • A channel interceptor? (it doesn't seem to be called on errors)
    • A no-op transformer ?
    • A JMS listener hook?

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

    Default

    It sounds like you might be describing the same thing that will be addressed by this issue: https://jira.springsource.org/browse/INT-907

    If so, feel free to watch/vote and even add your own feedback there.

    In the meantime, you could consider a catch block in the service-activator that is closest to the adapter. If you catch MessagingException you would be able to convert that into some fault response object (is that what you have in mind?). If available, the MesagingException does provide access to the 'failedMessage'.

  3. #3
    Join Date
    Jul 2008
    Posts
    21

    Default

    You're right, it's exactly the problem described in
    http://forum.springsource.org/showthread.php?t=76436

    I looked at the Error handling mechanism (chapter B.4 in Reference), I find it interesting. Why don't you affect an error handler at the channel level, may be it be synchronous or asynchronous? (To be backward compatible a default error handler could forward to the error channel in async channels). By the way, I regret that this error handler doesn't have access to the input message (only a Throwable).

    I looked at the Interceptor mechanism as well. It looks like an AOP aspect, but it's not as powerful: I have the "before" and "after-return" advice types, but I miss the "after-throwing" or "around" types. (one shoud note it's called "interceptor" but can't "intercept" a message (filter)).

  4. #4
    Join Date
    Jul 2008
    Posts
    21

    Default

    I looked at the "DefaultMessageListenerContainer overloading" solution you suggested to aznan. But the handleListenerException method doesn't have access to the message.

  5. #5
    Join Date
    Jul 2008
    Posts
    21

    Default

    My apologies, "interceptor" can indeed "intercept" a message (filter), by returning null message in preSend method.

  6. #6
    Join Date
    Oct 2008
    Location
    Warsaw, Poland
    Posts
    124

    Default

    Quote Originally Posted by Mark Fisher View Post
    In the meantime, you could consider a catch block in the service-activator that is closest to the adapter. If you catch MessagingException you would be able to convert that into some fault response object (is that what you have in mind?). If available, the MesagingException does provide access to the 'failedMessage'.
    Hi Mark,

    We're using SI 2.0 and flow configuration is as follows:

    Code:
    map-idle-channel-adapter -> splitter -> transformer -> service activator
    All of them are connected using direct channel without queue attribute so they are executed in the same thread. Unfortunately when exception is thrown in the splitter (the 2nd component) it's not propagated to the service activator which is the last component in our flow. We are getting the following stack trace:

    Code:
    Exception in thread "SimpleAsyncTaskExecutor-1" org.springframework.integration.MessageHandlingException: java.lang.RuntimeException: sdfsdfsdfsdfsdfsd
    	at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:76)
    	at org.springframework.integration.splitter.AbstractMessageProcessingSplitter.splitMessage(AbstractMessageProcessingSplitter.java:59)
    	at org.springframework.integration.splitter.AbstractMessageSplitter.handleRequestMessage(AbstractMessageSplitter.java:50)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:98)
    	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:110)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
    	at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:44)
    	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
    	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
    	at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
    	at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendMessage(AbstractReplyProducingMessageHandler.java:176)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendReplyMessage(AbstractReplyProducingMessageHandler.java:160)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.produceReply(AbstractReplyProducingMessageHandler.java:125)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(AbstractReplyProducingMessageHandler.java:119)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:101)
    	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:110)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
    	at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:44)
    	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
    	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
    	at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
    	at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149)
    	at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:92)
    	at org.springframework.integration.mail.ImapIdleChannelAdapter.access$800(ImapIdleChannelAdapter.java:41)
    	at org.springframework.integration.mail.ImapIdleChannelAdapter$IdleTask.run(ImapIdleChannelAdapter.java:126)
    	at java.lang.Thread.run(Thread.java:619)
    As you can see the exception is thrown from the AbstractMessageProcessingSplitter but is not propagated down to the service activator.

    Regards,
    Krzysztof

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

    Default

    If you are using 2.0, there is now an "error-channel" attribute on the <imap-idle-channel-adapter>. That can be used as a "catch all" for sending errors to a message flow.

  8. #8
    Join Date
    Oct 2008
    Location
    Warsaw, Poland
    Posts
    124

    Default

    Quote Originally Posted by Mark Fisher View Post
    If you are using 2.0, there is now an "error-channel" attribute on the <imap-idle-channel-adapter>. That can be used as a "catch all" for sending errors to a message flow.
    Thanks for this info. It works as I expected.

    Regards,
    Krzysztof

Posting Permissions

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