Page 1 of 4 123 ... LastLast
Results 1 to 10 of 34

Thread: Stuck on how to handle my exceptions

  1. #1
    Join Date
    Jun 2010
    Location
    Paris
    Posts
    106

    Question Stuck on how to handle my exceptions

    Hi,

    I've been stuck for a while on a simple case about how to handle exceptions correctly in my flows.
    Could somebody help me with that please ?

    Here is what I want to do :

    • Read a message from a JMS Queue in transaction (so no asynchronous flow possible)
    • Call a few transformers and service-activators (still within the JMS transaction)
    • Post the resulting message in another JMS Queue.
    • In case an exception occurs anywhere in this process, I want to catch the exception, log it and store the incoming message (in another JMS Queue for example). Then commit the transaction and process the next message.


    I thought of setting a ErrorHandler on the <message-driven-channel-adapter>, but even though the exception is catched and the ErrorHandler well executed, the exception is also thrown back, so the transaction is rollbacked ! Thus, the message never gets committed and is processed over and over...

    This seems quite a simple case, but no clue how to deal exceptions in this case... Any idea that could help me out?

    Thank you very much!

    Pierre

  2. #2
    Join Date
    Jan 2008
    Location
    Mohnton, PA USA (that's near Philadelphia)
    Posts
    2,148

    Default

    Ok, are you sending any reply message back to the sender, because if you do the jms:inbound-gateway has exception-mapper property, which allows you set InboundMessageMapper implementation converting Exception to a successful message. Would that help?

  3. #3
    Join Date
    Jun 2010
    Location
    Paris
    Posts
    106

    Default

    Hi Oleg and thank you for your answer.
    Unfortunately, I'm not sending any reply message back to the sender.

  4. #4
    Join Date
    Jan 2008
    Location
    Mohnton, PA USA (that's near Philadelphia)
    Posts
    2,148

    Default

    Just wanted to let you know that I am still looking into this, should get back to you shortly.

  5. #5
    Join Date
    Jun 2010
    Location
    Paris
    Posts
    106

    Default

    Thank you Oleg, I appreciate.

    By the way, I was wondering something: Is it normal that, after the ErrorHandler is called, the exception is still thrown back? If an ErrorHandler is defined, is there really a point in having the exception thrown all the way back to the caller? Isn't it precisely why we defined an ErrorHandler?

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

    Default

    Pierre,

    You are right that an ErrorHandler on the MessageListener container should be able to suppress the Exceptions from being propagated.

    Can you provide more detail about the ErrorHandler implementation you are using and also how it's being configured?

    Thanks,
    Mark

  7. #7

    Default

    I have the same requirement, we are using AMQ DLQ strategy to handle all receiver exceptions, but ideally we want to be able to catch the exception and send it onto a an invalid message channel http://www.eaipatterns.com/InvalidMessageChannel.html and then use the SI exception router to kick in depending on the type of exception, but still allowing the underlying transaction to commit.


    I was sort of hoping it would have been supported as part of the following JIRA fixed https://jira.springframework.org/browse/INT-907

    Thanks

  8. #8
    Join Date
    Jun 2010
    Location
    Paris
    Posts
    106

    Default

    You'll find below the smallest configuration to reproduce my case.

    Actually, it looks more like a Spring JMS problem than a Spring Integration one as the errorHandler is part of the class org.springframework.jms.listener.AbstractMessageLi stenerContainer

    That's the only way I found to handle my exceptions with Spring Integration in a synchronous flow (I know we have already discussed this subject before, but I still hope someday to see a more flexible way (per-endpoint strategy) to handle exceptions in SI :-)).

    Spring Context

    Code:
    <int-jms:message-driven-channel-adapter container="jmsListener" channel="channel1"  />
    
    <bean id="jmsListener" parent="queueListenerMce">
    	<property name="destinationName" value="MCEHoldingForexErrorQueue" />
    	<property name="sessionTransacted" value="true" />
    	<property name="errorHandler">
    		<bean class="com.sample.MyErrorHandler" />
    	</property>
    </bean>
    	
    <int:publish-subscribe-channel id="channel1" />
    
    <int-stream:stdout-channel-adapter channel="channel1" append-newline="true" />
    
    <int:service-activator input-channel="channel1" output-channel="nullChannel">
    	<bean class="com.sample.ExceptionThrower" />
    </int:service-activator>

    com.sample.ExceptionThrower

    Code:
    public class ExceptionThrower {
    	public void throwException(String ok) {
    		throw new RuntimeException("Oh oh...");
    	}
    }
    com.sample.MyErrorHandler

    Code:
    public class MyErrorHandler implements ErrorHandler {
    	@Override
    	public void handleError(Throwable arg0) {
    		System.out.println("Hey, the message failed!");
    	}
    }

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

    Default

    I just want to clarify one thing...

    Earlier you mentioned this:
    even though the exception is catched and the ErrorHandler well executed, the exception is also thrown back, so the transaction is rollbacked !
    Then, you mentioned this:
    the ErrorHandler is called, the exception is still thrown back? If an ErrorHandler is defined, is there really a point in having the exception thrown all the way back to the caller?
    I don't think the Exception is actually being *thrown back* anywhere. The rollback is triggered prior to the ErrorHandler being invoked, because if the Session is transactional it will always rollback for any Exception (JMSException or RuntimeException).

    So, the first thing that I'd like to clarify is why you are using a transactional Session if you are *always* going to commit?

    I've got a few other questions, but I want to take them one at a time

    Thanks,
    Mark

  10. #10
    Join Date
    Jun 2010
    Location
    Paris
    Posts
    106

    Default

    Good question.

    We can't afford losing any message in case of a "crash" (if the JVM shuts down unexpectedly, if an OutOfMemoryError occurs, ...), so we need to ensure that the message has been posted on the second queue before committing the first one.

    (Note: On the other hand, we can afford having duplicate messages, as we are able to identify them)

    Next question?

Tags for this Thread

Posting Permissions

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