Announcement Announcement Module
Collapse
No announcement yet.
Handling mail outbound exceptions Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Handling mail outbound exceptions

    Hello,

    I have a simple flow that sends a mail via an outbound adapter and logs the message:

    Code:
    	<int:channel id="channel.send" />
    	<mail:outbound-channel-adapter order="1" channel="channel.send" mail-sender="mailSender"/>	
    	<bean id="logger" class="com.blah.MessageLogger" />
    	<int:service-activator order="2" input-channel="channel.send"
    		ref="logger" />
    This works as expected.

    I would like to implement exception handling, so if the email can not be sent (ie mail server down), I can modify the message and log it.

    I can't find the documentation on exception handling in this instance. Can anyone help?


    John

  • #2
    Hello

    The <mail:outbound-channel-adapter> is a tipical Spring Integration component, so it has the same functionality around Exceptions as others. This paragraph should help you: http://static.springsource.org/sprin...e-errorhandler

    However I see a problem in your config:
    1. You have a DirectChannel and two his subscribers.
    2. By default this channel use on background UnicastingDispatcher with RoundRobinLoadBalancingStrategy
    3. So, the first Message will be send to <mail:outbound-channel-adapter>, but the second to <int:service-activator> and so on, through the times. Confused?

    To allow to work ordering you should make this:
    HTML Code:
    <channel id="channel.send">
    	<dispatcher load-balancer="none"/>
    </channel>
    Now your Message will always be sended to <mail:outbound-channel-adapter>, and it will be sended to <int:service-activator> only when Exception causes on email sending process.

    Is it what are you looking for?

    Cheers,
    Artem

    Comment


    • #3
      Hello

      That's helpful as I didn't realise I needed <dispatcher load-balancer="none"/> to make order work. Oddly, it was sending the message to both the mail outbound adapter and the logger. I stepped through the SI code to ensure it did.

      But, what I'm looking for is information on how to deal with exceptions from the mail adapter. ie I want to catch it and set a value on the message header.

      I tried adding a service activator to the default errorChannel but it's not called by the (deliberately failing) mail outbound adapter:

      Code:
      	<bean id="errorHandler" class="com.blah.ErrorHandler" />
      	<int:service-activator input-channel="errorChannel" ref="errorHandler" />
      John
      Last edited by jbakerc; Aug 15th, 2012, 06:27 AM.

      Comment


      • #4
        I want to catch it
        So, read the Manual, where I've pointed.
        And also for logging I recommend to use <wire-tap>

        Comment


        • #5
          Yes, I read the manual, added a service activator listening to errorChannel, stepped through the code and when the exception is thrown by the mail outbound adapter, the service activator isn't called.

          Comment


          • #6
            Update, the following is required to make the UnicastDispatcher stop and throw an exception when iterating through the list of message handlers:

            Code:
            		<int:dispatcher load-balancer="none" failover="false" />
            However, whilst that spits out the exception to the stdout log, it doesn't seem to call my error handler.

            If it helps, I'm reading the original message from JMS.

            Comment


            • #7
              Case closed. The JMS adapter needs to be explicitly told about the error channel, which I feel is not a great solution given it should use the default errorChannel automatically as per the documentation.

              Code:
              	<int-jms:message-driven-channel-adapter ... error-channel="errorChannel" />
              Cleric, as a matter of interest, how would I re-write the mail/log example above without using order? ie can the mail adapter push the message to another channel when it completes? I couldn't see an out channel attribute.

              Comment


              • #8
                how would I re-write the mail/log example above without using order?
                What does your com.blah.MessageLogger do with the Message?
                ie can the mail adapter push the message to another channel when it completes?
                No, it can't. It is a one-way component. By the way: if send an email message manualy via javax.mail.Session, do you have any return ?

                What do you want to get with "it completes" case?
                Maybe this will be enough:
                HTML Code:
                <int:publish-subscribe-channel id="channel.send" />
                <mail:outbound-channel-adapter order="1" channel="channel.send" mail-sender="mailSender"/>	
                <int:service-activator ref="afterSendEmailService"/>
                Here "channel.send" has several subscribers and the channel sends inbound Message to them all.
                But it will be done one by one at the same thread. So, if your <mail:outbound-channel-adapter> throws Exception the Message won't be sended to the <int:service-activator>

                Is it appropriate?

                Comment


                • #9
                  HTML Code:
                  <int:publish-subscribe-channel id="channel.send" />
                  <mail:outbound-channel-adapter order="1" channel="channel.send" mail-sender="mailSender"/>	
                  <int:service-activator ref="afterSendEmailService"/>
                  Yes, this is what I was looking for, and what I was trying to do with the order in the previous snippet.

                  Comment


                  • #10
                    It's a pity that a new message is passed to the error handler, and not the existing message with a new payload. From MessagingGatewaySupport:

                    Code:
                    		catch (Exception e) {
                    			if (this.errorChannel != null) {
                    				this.messagingTemplate.send(this.errorChannel, new ErrorMessage(e));
                    			}
                    			else {
                    				this.rethrow(e, "failed to send message");
                    			}
                    I wanted to read values from the headers in order to help deal with the error.

                    Comment


                    • #11
                      The payload of the ErrorMessage is a MessagingException - it has 2 properties cause (the actual exception) and failedMessage - the message that failed.

                      Comment


                      • #12
                        I wanted to read values from the headers in order to help deal with the error.
                        Have you take a look into ErrorMessage payload? Which Exception is it?
                        Let me guess: it is an org.springframework.integration.MessagingException and the last one contains a self-explained property failedMessage.

                        WDYT?

                        Comment


                        • #13
                          Well, there is a failed message but it's the input message, ie what was read from JMS, and not the message that went into the mail outbound adapter that caused the problem
                          Last edited by jbakerc; Aug 15th, 2012, 09:48 AM.

                          Comment


                          • #14
                            Originally posted by Cleric View Post

                            To allow to work ordering you should make this:
                            HTML Code:
                            <channel id="channel.send">
                            	<dispatcher load-balancer="none"/>
                            </channel>
                            Now your Message will always be sended to <mail:outbound-channel-adapter>, and it will be sended to <int:service-activator> only when Exception causes on email sending process.
                            define order for mail outbound adapter and service activator, also using load-balancer in channel, it works to me.

                            Comment

                            Working...
                            X