Page 1 of 2 12 LastLast
Results 1 to 10 of 20

Thread: ErrorHandler strategy for 2.0 ?

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

    Default ErrorHandler strategy for 2.0 ?

    Dear all,

    Do you think it might be possible to have JIRA INT-628 (ErrorHandler Strategy) implemented for the 2.0 release?

    My flows are quite long and thus I need to be able to control quite precisely how to handle errors at each endpoint of my flow. This JIRA regarding error handling at a low level (I mean, channel or endpoint) is definitely a major prerequisite of the push to Production of my project.

    Pierre

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

    Default

    Could you please elaborate on your use case in more details. There are many ways to handle errors in SI, some always been there some new, so more details would help.

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

    Default

    Hi Oleg and thank you for your reply.

    Here's one of the many use cases where I'd need some error handling. I provided a sample of my XML configuration below (some channels are defined in other files so don't bother looking for them).

    There is a succession of endpoints, and for each endpoint (or channel), I would have liked to configure how to handle the errors.

    All my service activators may throw exceptions: depending on the service activator (and possibly, but not essentially, depending on the exception), I would like to send an email; for others, route the message to another channel or simply drop the message. Same thing for my customized splitters and transformers.
    All these behaviours could be quickly implemented if there was a configurable "error-channel" attribute for each of these endpoints.

    Note that I'm working in a synchronized flow here. But even in an unsynchronized flow, more customization would really be nice to handle errors differently depending on where and why the message failed to be processed.


    Any solution I would have missed to do this?


    Code:
    <int-file:inbound-channel-adapter channel="fileChannel" directory="/Tests" filename-pattern=".*\.xml" auto-startup="false">
    	<int:poller>
    		<int:interval-trigger interval="1000" />
    	</int:poller>
    </int-file:inbound-channel-adapter>
    
    <int:channel id="fileChannel" />
    	
    <int-file:file-to-string-transformer input-channel="fileChannel" output-channel="fileContentChannel" />
    
    <int:channel id="fileContentChannel" />
    
    <int:header-enricher input-channel="fileContentChannel" output-channel="headersChannel">
    	<int:header name="rawInputMessage" expression="payload" />
    	<int:header name="auditProcess" value="EPS" />
    </int:header-enricher>
    	
    <int:channel id="headersChannel" />
    	
    <int:header-value-router input-channel="headersChannel" header-name="technicalRedelivery" default-output-channel="noRedeliveryChannel">
    	<int:mapping value="true" channel="duplicateChannel" />
    </int:header-value-router>
    
    <int:channel id="noRedeliveryChannel" />
    
    <int:chain input-channel="noRedeliveryChannel" output-channel="endOfChainChannel">
    
    	<int:service-activator ref="trnGenerator" method="generateTrni" />
    
    	<int:service-activator ref="auditMessagePersistence" />
    
    	<int-xml:unmarshalling-transformer unmarshaller="JaxbMarshaller" />
    
    	<int:splitter method="splitMessage">
    		<bean class="com.RuleSolverFlowDetailsSplitter">
    			<property name="dataSource" value="DKG" />
    			<property name="ruleSolverTreeName" value="DKG" />
    		</bean>
    	</int:splitter>
    
    	<int:service-activator ref="trnGenerator" method="generateTrno" />
    
    </int:chain>
    	
    <int:channel id="endOfChainChannel">
    	<int:interceptors>
    		<int:wire-tap channel="auditPendingChannel"/>
    	</int:interceptors>
    </int:channel>
    
    <!-- To be completed... -->
    <int:bridge input-channel="endOfChainChannel" output-channel="nullChannel" />
    
    <!-- CHANNELS ASIDE -->
    	
    <int:channel id="duplicateChannel" />
    
    <int-xml:unmarshalling-transformer unmarshaller="JaxbMarshaller" input-channel="duplicateChannel" output-channel="auditCheckDuplicateChannel"/>
    
    <!-- BEANS DEFINITIONS -->
    
    <bean id="trnGenerator" parent="abstractTrnGeneratorServices">
    	<property name="sequenceName" value="EPS" />
    	<property name="prefix" value="EPS" />
    </bean>
    Thank you!

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

    Default

    Any idea how to handle errors at the endpoint level ?

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

    Default

    Well, the $errorChannel could always be specified with header-enricher,but you must understand how that works.
    If you are in the sync flow (all endpoints connected via direct channels), then the entire flow is on the same thread, so the exception will be re-thrown back to the original caller and you can do whatever it is you want to do with it including notifying others about what happened.
    If you are in the async flow where a thread does not know who the original caller is if it catches the exception it will be looking for the $errorChannel header.
    Does that help?

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

    Default

    Thank you Oleg for these details.
    I know how error handling currently works in sync and async flows, but the problem is that this behaviour doesn't allow enough customization:

    • In a sync flow, depending on the endpoint from which the exception is thrown, I would like the behaviours to be different.

      For instance, if the splitter fails with an exception, I would like to send an email with the message "Warning! The splitter failed for the reason: + exception.getMessage()". However, if one of the service-activator "trnGenerator" fails, I would like to call another service-activator. etc...

      If I catch the Exception at the inbound-channel-adapter point, I will only get a MessagingException and won't be able determine in which endpoint it failed (or I would have to look into channel history, which is definitely not an elegant solution) and decide the right action to do. Or if I eventually manage to do so, all the decision would be stored in one single place.

      If there was an error-handler attribute for each endpoint (service-activator, splitter, ...), this would be much more flexible, wouldn't it?

    • In an async flow, to have this flexibility, I would need to have an header-enricher to set the $errorChannel before each endpoint for which I need a specific behaviour.
      Again, an error-handler attribute for each endpoint would be much simpler.


    All in all, having the "error-handler" attribute for each endpoint would allow more flexibility and there wouldn't be any difference any more between sync and async flows regarding error handling.

    That's why I found JIRA INT-628 so interesting and was wondering if there was any plan to implement it.

    Note: Some default implementations of error handlers could also be suggested to the user such as a "moveToChannel" or "dropMessage" handlers.

    What do you think?
    Last edited by plecesne; Sep 2nd, 2010 at 08:11 AM.

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

    Default

    Any comment?

  8. #8
    Join Date
    Nov 2008
    Location
    Swansea, Wales
    Posts
    202

    Default

    This would be a great feature. I've had to make my sync flows async just to get the error handling behaviour I want. With the addition of header enrichers for the required error channel

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

    Default

    Would the new "exceptionMapper" support on a gateway potentially handle your use-case? (see: http://static.springsource.org/sprin...#gateway-proxy)

    It has been our goal to use "gateways" (proxies) as request/reply components that hide the details of sync vs. async downstream message flows (e.g. if a error occurs in an async flow, the gateway will still receive it and then rethrow is so that it seems no different than if it happened synchronously). The 'exceptionMapper' then provides a hook to convert errors to valid Messages (but typically "error messages" or "faults") rather than having them re-thrown to the caller.

    The problem with a general error-handler strategy is that it might be at odds with our use of the errorChannel to provide that consistency between sync and async flows. Also, different components can react differently. For example, you mentioned "drop mesages" as a strategy option, and that is exactly one of the options for a Filter, but it does not seem appropriate on other components (e.g. "Service Activator").

    Finally, consider the fact that those various components can actually share the same "error-channel", but that channel can itself have a Router connected. This way, you can rely on the same messaging patterns for your error flows. Certain types of error might result in an email while other types are only logged, etc.

    Do any of these ideas seem worth exploration? I hope it doesn't seem like we're just trying to avoid adding that one feature... it's actually a relatively trivial thing, but we are often walking a very thin line between flexibility and overwhelming people with too many options for handling a particular situation.

    Thanks,
    Mark

  10. #10
    Join Date
    Nov 2008
    Location
    Swansea, Wales
    Posts
    202

    Default

    I'm happy with what I've done (I think) and defo understand trying to not have too many options, it's just that I've had to make my flow async in order to achieve what I want which I had no real reason otherwise to do.

    In my use case I have a message flow using gateway proxy facade bean that ultimateley sends a web service request and on a soap fault I need to log the fault to the database as well as an exception being thrown to the caller. I suppose I could have used AOP for this which may or may not be better but what I currently have done is made my gateway's request channel a queue channel to break the sync so faults are put on the errorChannel. In fact I override the error channel header in these cases so the faults go to my own error channel. I then process those errors routing to 2 different channels. The first one logs the fault to the database and the second one gets the reply channel from the failed message and puts an ErrorMessage on that channel so the error is thrown to the caller as per how it would if everything was sync.

    In summary I think there are use cases where a developer may need to do more than just have the error re-thrown and the hook to do this to me is either making use of the errorChannel or using AOP. I don't think exceptionMapper allows me to achieve this behaviour.
    Last edited by rhart; Sep 7th, 2010 at 06:32 AM.

Posting Permissions

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