From 2e3a0487e0df29f264cace218f49aafc76b8e393 Mon Sep 17 00:00:00 2001 From: Mark Fisher Date: Wed, 26 Nov 2008 05:52:44 +0000 Subject: [PATCH] Added discussion of error handling (INT-457). --- .../src/configuration.xml | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/spring-integration-reference/src/configuration.xml b/spring-integration-reference/src/configuration.xml index 69f33943a0..d853368134 100644 --- a/spring-integration-reference/src/configuration.xml +++ b/spring-integration-reference/src/configuration.xml @@ -91,8 +91,8 @@ -
- Configuring the Message Bus +
+ Configuring the Task Scheduler In Spring Integration, the ApplicationContext plays the central role of a Message Bus, and there are only a couple configuration options to be aware of. First, you may want to control the central TaskScheduler instance. @@ -108,20 +108,61 @@ When the endpoints are concurrency-enabled with their own 'taskExecutor' reference, the invocation of the handling methods will happen within that executor's thread pool and not the main scheduler pool. However, when no task-executor is provided for an endpoint's poller, it will be invoked in the dispatcher's thread - (with the exception of subscribable channels where the subscribers will be invoked directly). + (with the exception of subscribable channels where the subscribers will be invoked directly). The next + section will describe what happens if Exceptions occur within the asynchronous invocations. + +
+ +
+ Error Handling + + As described in the overview at the very beginning of this manual, one of the main motivations behind a + Message-oriented framework like Spring Integration is to promote loose-coupling between components. The + Message Channel plays an important role in that producers and consumers do not have to know about each + other. However, the advantages also have some drawbacks. Some things become more complicated in a very + loosely coupled environment, and one example is error handling. - The Message Bus supports error handling for its components in the form of a configurable error channel, - and it will first check for a channel bean named "errorChannel" within the context: + When sending a Message to a channel, the component that ultimately handles that Message may or may not + be operating within the same thread as the sender. If using a simple default DirectChannel (with the + <channel> element that has no <queue> sub-element), the handling will be in the same thread. + In that case, if an Exception is thrown, it will be catch-able by the sender (or it may propagate past + the sender if it is an uncaught RuntimeException). So far, everything is fine. This is the same behavior + as an Exception-throwing operation in a normal call stack. However, when adding the asynchronous aspect, + things become much more complicated. For instance, if the 'channel' element does + provide a 'queue' sub-element, then the component that handles the Message will be + operating in a different thread than the sender. The sender may have dropped the Message and moved on to + other things. There is no way for the Exception to be thrown directly back to that sender using standard + Exception throwing techniques. Instead, to handle errors for asynchronous processes requires an + asynchronous error-handling mechanism as well. + + + Spring Integration supports error handling for its components by publishing errors to a Message Channel. + Specifically, the Exception will become the payload of a Spring Integration Message. That Message will + then be sent to a Message Channel that is resolved in a way that is very similar to the 'replyChannel' + resolution. First, if the request Message being handled at the time the Exception occurred contains + an 'errorChannel' header (the header name is defined in the constant: MessageHeaders.ERROR_CHANNEL), + the ErrorMessage will be sent to that channel. Otherwise, the error handler will send to a "global" + channel whose bean name is "errorChannel" (this is also defined as a constant: + IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME). + + + Whenever relying on Spring Integration's XML namespace support, a default "errorChannel" bean will be + created behind the scenes. However, you can just as easily define your own if you want to control the + settings. ]]> - When exceptions occur in a scheduled poller task's execution, those exceptions will be wrapped in + + + The most important thing to understand here is that the Messaging-based error handling will only apply + to Exceptions that are thrown by a Spring Integration task that is executing within a TaskExecutor. + This does not apply to Exceptions thrown by a handler that is operating within + the same thread as the sender (e.g. through a DirectChannel as described above). However, when + Exceptions occur in a scheduled poller task's execution, those exceptions will be wrapped in ErrorMessages and sent to the 'errorChannel' by default. To enable global error handling, simply register a handler on that channel. For example, you can configure Spring Integration's ErrorMessageExceptionTypeRouter as the handler of an endpoint that is subscribed to the 'errorChannel'. That router can then spread the error messages across multiple channels based on - Exception type. However, since most of the errors will already have been wrapped in - MessageDeliveryException or MessageHandlingException, - the ErrorMessageExceptionTypeRouter is typically a better option. + Exception type.