Page 3 of 4 FirstFirst 1234 LastLast
Results 21 to 30 of 34

Thread: Stuck on how to handle my exceptions

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

    Default

    Yes, that's perfect for now.
    Thanks a lot, Mark.

  2. #22
    Join Date
    Jan 2010
    Posts
    124

    Default

    Hi Pierre,
    This is exactly what iam doing now and i is going into production on Jan 1st.
    I am using Websphere SI bus as default JMSrovider and using Spring integration 2.0.0.RC1 for my standalone consumer app.

    I am using Message driven channel adapter.
    Logic:
    1) Receive a message
    2) Process the message and do a http Post to Our customer Url.
    3) If step 2 fails, throw an exception. This way the message is retained in my JMS provider. In JMs provider there is a setting for On exception to block it for xxx millisecs. I am blocking it for 30 minutes before it is sent to My Standalone spring integration app.

    I am using deliveryCount in the message header as my retry count for my application logic. If retry fails for 6th time, i redirect the message to a different Queue destination on websphere SI Bus for further processing.

    so, you could do that, if your jms provider gives you the option for on exception handling.
    Hope this helps.
    --sri
    Quote Originally Posted by plecesne View Post
    Sounds good!

    I have a few questions though. (I didn't want to post them on the JIRA if they are not relevant).

    1. Will it be the MessagingException that will be sent on the error-channel?

    2. Let's say I have the following flow:
    Code:
    Inbound CA --> SA #1 --> SA #2 --> SA #3 --> Outbound CA
    
    CA : Channel Adapter
    SA : Service Activator
    --> : Direct Channel
    Now, the behaviour that I want is:
    - If an exception is thrown within SA #1 or SA #2, I want to redirect the failed message to errorChannel and handle that properly (store the message, and send an email, for instance)
    - If an exception is thrown within SA #3 or Outbound CA due to a ConnectException or RemoteException, I want to retry 1000 times (with a delay of 10s between each try) and if it still fails, redirect the message to an errorChannel.


    Is it a case that will be handled with the RetryInterceptor (JIRA 343) or is it something that could be added to this new "error-channel" attribute feature? Or is it already something possible?
    If this case could be handled, this would make it the perfect "error handling kit" as I believe most cases could then be handled.

    Sorry for the long thread, and thank you for caring

    Pierre

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

    Default

    Hi Sri and thank you for your help.

    I'm not sure if my JMS Provider has such options, but I will check as these sounds as interesting options.

    The retry system is interesting in your example, but this solution is still not good enough for my use cases:
    Let's take my example again (In-CA, SA#1, SA#2, ...) and let's say that the exception is always thrown in SA#2 (due to a disconnected remote partner), and let's say that SA#1 generates a unique ID: as the retry logic is located in the JMS Provider, if I retry 5 times, I will go through SA#1 five times and thus generate five unique ID for the same message... If I retry 10000 times, I will then waste 10000 unique ID.
    That's why I need a retry system located at SA#2 and not at the beginning of my flow. I really hope that INT-343 will be able to solve this case.

    Thank you anyway for sharing your tips.

    Pierre

  4. #24
    Join Date
    Jan 2010
    Posts
    124

    Default

    Ah, I understand it now.
    did you look at Delayer component? You can place a delayer after SA#2 and retry that as many times as you want.

    --sri
    Quote Originally Posted by plecesne View Post
    Hi Sri and thank you for your help.

    I'm not sure if my JMS Provider has such options, but I will check as these sounds as interesting options.

    The retry system is interesting in your example, but this solution is still not good enough for my use cases:
    Let's take my example again (In-CA, SA#1, SA#2, ...) and let's say that the exception is always thrown in SA#2 (due to a disconnected remote partner), and let's say that SA#1 generates a unique ID: as the retry logic is located in the JMS Provider, if I retry 5 times, I will go through SA#1 five times and thus generate five unique ID for the same message... If I retry 10000 times, I will then waste 10000 unique ID.
    That's why I need a retry system located at SA#2 and not at the beginning of my flow. I really hope that INT-343 will be able to solve this case.

    Thank you anyway for sharing your tips.

    Pierre

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

    Default

    Errr... I'm not sure how that would work.

    I only want to retry when an exception occurs. If an exception occurs in SA#2, I won't reach anything that is placed after SA#2... And if no exception occurs in SA#2, I don't want a delay or any retry.
    Moreover, the delayer only adds a delay, there is no retry logic within this component.

    If you had an idea in mind, could you be more specific? I think I didn't get it properly...

  6. #26
    Join Date
    Jan 2010
    Posts
    124

    Default

    Not sure where you want to implement the retry logic, but here is the algorithm.

    In the service Activator, you want to implement the retry logic, inject MessagingTemplate object and a Channel reference (Say delayerChannel).

    Once you catch the exception, Create a copy of the failed message and increment retryLimit header value. (This is a custom header you need to add for every message from start of the flow.). Using MessagingTemplate send this new message to delayerChannel. Once it is on the delayerChannel, it will go through delayer element, it will be delayed for xxx ms and then will be send back to your Service Activator for resending.

    This is little over engineering for retry logic, but will work.
    Key elements in this are, retryLimit custom header and creating a new copy of the failed message for every failed attempt and incrementing the retryLimit header value.
    Hope this is clear.
    --sri


    Quote Originally Posted by plecesne View Post
    Errr... I'm not sure how that would work.

    I only want to retry when an exception occurs. If an exception occurs in SA#2, I won't reach anything that is placed after SA#2... And if no exception occurs in SA#2, I don't want a delay or any retry.
    Moreover, the delayer only adds a delay, there is no retry logic within this component.

    If you had an idea in mind, could you be more specific? I think I didn't get it properly...

  7. #27
    Join Date
    Jun 2010
    Location
    Paris
    Posts
    106

    Default

    Oh now I see. Well, indeed, this would work. With quite a big dependence to SI API, but it would probably work
    Sounds a bit too intrusive to me, but thank you for the advice, sri!

  8. #28
    Join Date
    Jan 2010
    Posts
    124

    Default

    If your jms provider has the on Exception functionality, you can send all failed messages to a new destination and then receive the messages from the same destination for all failed messages using another Inbound adapter,
    --sri
    Quote Originally Posted by plecesne View Post
    Oh now I see. Well, indeed, this would work. With quite a big dependence to SI API, but it would probably work
    Sounds a bit too intrusive to me, but thank you for the advice, sri!

  9. #29
    Join Date
    Jun 2005
    Posts
    4,241

    Default

    This does seem to be a Spring JMS issue really, but Spring Integration adds a layer of smarts on top of that, so there might be some hooks you can use. To prevent the rollback you need to catch the exception and deal with it in the MessageListener, which in this case is the downstream message flow.

    Spring Integration sensibly doesn't provide an exception handling strategy for synchronous flows - it's much easier to handle them in the calling thread. The problem here is that the calling thread belongs to the MessageListenerContainer, deep in Spring JMS.

    You could start by looking at customizing the dispatcher for the downstream channel. By default it does catch exceptions and tries to deliver the message to other subscribers (see UnicastingDispatcher). In your case you want the fallback subscriber to get not only the message but the exception as well - you can do that by implementing an alternate form of the dispatcher in a few lines probably.

    Or you could put a special service activator downstream of the message listener that just delegates to a gateway, pushing the message on downstream but taking control of the calling thread, and allowing you to catch exceptions and handle them.

    Or you could add an AOP interceptor to the downstream Channel.send() and do the same thing. (This is likely to be the approach we take in Spring Integration 2.1 to add declarative retry and recovery to message flows generally.)

  10. #30
    Join Date
    Jan 2010
    Posts
    124

    Default

    I am actually using special service activator downstream and also ResponseHandler for HttpRequestMessageHandler (INT-1587) to get the retry functionality and some exception handling.

    Yes, you are right, this is JMS issue and we need handle of calling thread and or Exception handling mechanish at the begining of the flow. This way we can handle exceptions and account for the messages.
    Thanks
    sri

    Quote Originally Posted by Dave Syer View Post
    This does seem to be a Spring JMS issue really, but Spring Integration adds a layer of smarts on top of that, so there might be some hooks you can use. To prevent the rollback you need to catch the exception and deal with it in the MessageListener, which in this case is the downstream message flow.

    Spring Integration sensibly doesn't provide an exception handling strategy for synchronous flows - it's much easier to handle them in the calling thread. The problem here is that the calling thread belongs to the MessageListenerContainer, deep in Spring JMS.

    You could start by looking at customizing the dispatcher for the downstream channel. By default it does catch exceptions and tries to deliver the message to other subscribers (see UnicastingDispatcher). In your case you want the fallback subscriber to get not only the message but the exception as well - you can do that by implementing an alternate form of the dispatcher in a few lines probably.

    Or you could put a special service activator downstream of the message listener that just delegates to a gateway, pushing the message on downstream but taking control of the calling thread, and allowing you to catch exceptions and handle them.

    Or you could add an AOP interceptor to the downstream Channel.send() and do the same thing. (This is likely to be the approach we take in Spring Integration 2.1 to add declarative retry and recovery to message flows generally.)

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
  •