View Full Version : Error handling in direct channels
gquintana
Dec 14th, 2009, 09:57 AM
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?
Mark Fisher
Dec 14th, 2009, 10:44 AM
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'.
gquintana
Dec 14th, 2009, 02:47 PM
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)).
gquintana
Dec 14th, 2009, 02:52 PM
I looked at the "DefaultMessageListenerContainer overloading" solution you suggested to aznan. But the handleListenerException method doesn't have access to the message.
gquintana
Dec 15th, 2009, 02:00 AM
My apologies, "interceptor" can indeed "intercept" a message (filter), by returning null message in preSend method.
krzychu
Dec 14th, 2010, 09:28 AM
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:
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:
Exception in thread "SimpleAsyncTaskExecutor-1" org.springframework.integration.MessageHandlingExc eption: java.lang.RuntimeException: sdfsdfsdfsdfsdfsd
at org.springframework.integration.handler.MethodInvo kingMessageProcessor.processMessage(MethodInvoking MessageProcessor.java:76)
at org.springframework.integration.splitter.AbstractM essageProcessingSplitter.splitMessage(AbstractMess ageProcessingSplitter.java:59)
at org.springframework.integration.splitter.AbstractM essageSplitter.handleRequestMessage(AbstractMessag eSplitter.java:50)
at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.handleMessageInternal(A bstractReplyProducingMessageHandler.java:98)
at org.springframework.integration.handler.AbstractMe ssageHandler.handleMessage(AbstractMessageHandler. java:78)
at org.springframework.integration.dispatcher.Unicast ingDispatcher.doDispatch(UnicastingDispatcher.java :110)
at org.springframework.integration.dispatcher.Unicast ingDispatcher.dispatch(UnicastingDispatcher.java:9 7)
at org.springframework.integration.channel.AbstractSu bscribableChannel.doSend(AbstractSubscribableChann el.java:44)
at org.springframework.integration.channel.AbstractMe ssageChannel.send(AbstractMessageChannel.java:157)
at org.springframework.integration.channel.AbstractMe ssageChannel.send(AbstractMessageChannel.java:128)
at org.springframework.integration.core.MessagingTemp late.doSend(MessagingTemplate.java:288)
at org.springframework.integration.core.MessagingTemp late.send(MessagingTemplate.java:149)
at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.sendMessage(AbstractRep lyProducingMessageHandler.java:176)
at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.sendReplyMessage(Abstra ctReplyProducingMessageHandler.java:160)
at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.produceReply(AbstractRe plyProducingMessageHandler.java:125)
at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.handleResult(AbstractRe plyProducingMessageHandler.java:119)
at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.handleMessageInternal(A bstractReplyProducingMessageHandler.java:101)
at org.springframework.integration.handler.AbstractMe ssageHandler.handleMessage(AbstractMessageHandler. java:78)
at org.springframework.integration.dispatcher.Unicast ingDispatcher.doDispatch(UnicastingDispatcher.java :110)
at org.springframework.integration.dispatcher.Unicast ingDispatcher.dispatch(UnicastingDispatcher.java:9 7)
at org.springframework.integration.channel.AbstractSu bscribableChannel.doSend(AbstractSubscribableChann el.java:44)
at org.springframework.integration.channel.AbstractMe ssageChannel.send(AbstractMessageChannel.java:157)
at org.springframework.integration.channel.AbstractMe ssageChannel.send(AbstractMessageChannel.java:128)
at org.springframework.integration.core.MessagingTemp late.doSend(MessagingTemplate.java:288)
at org.springframework.integration.core.MessagingTemp late.send(MessagingTemplate.java:149)
at org.springframework.integration.endpoint.MessagePr oducerSupport.sendMessage(MessageProducerSupport.j ava:92)
at org.springframework.integration.mail.ImapIdleChann elAdapter.access$800(ImapIdleChannelAdapter.java:4 1)
at org.springframework.integration.mail.ImapIdleChann elAdapter$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
Mark Fisher
Dec 14th, 2010, 10:02 AM
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.
krzychu
Dec 15th, 2010, 04:06 AM
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
Powered by vBulletin® Version 4.2.1 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.