diff --git a/src/reference/asciidoc/configuration.adoc b/src/reference/asciidoc/configuration.adoc index 5371ddc363..7fcd6bb1e3 100644 --- a/src/reference/asciidoc/configuration.adoc +++ b/src/reference/asciidoc/configuration.adoc @@ -147,18 +147,25 @@ Some things become more complicated in a very loosely coupled environment, and o 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 `` element that has no `` sub-element and no 'task-executor' attribute), -the Message-handling will occur in the same thread as the Message-sending. +the Message-handling will occur in the same thread that sends the initial message. In that case, if an `Exception` is thrown, it can be caught 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. + +A message flow that runs on a caller thread might be invoked via a `Messaging Gateway` (see <>) or a `MessagingTemplate` (see <>). +In either case, the default behavior is to throw any exceptions to the caller. +For the `Messaging Gateway`, see <> for details about how the exception is thrown and how to configure the gateway to route the errors to an error channel instead. +When using a `MessagingTemplate`, or sending to a `MessageChannel` directly, exceptions are always thrown to the caller. + +When adding asynchronous processing, things become rather 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 same is true when an `ExecutorChannel` is used. The sender may have dropped the `Message` into the channel 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. +Instead, handling 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. +Specifically, the `Exception` will become the payload of a Spring Integration `ErrorMessage`. That `Message` will then be sent to a Message Channel that is resolved in a way that is 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. diff --git a/src/reference/asciidoc/gateway.adoc b/src/reference/asciidoc/gateway.adoc index ad563bd7ca..356da0de60 100644 --- a/src/reference/asciidoc/gateway.adoc +++ b/src/reference/asciidoc/gateway.adoc @@ -392,6 +392,8 @@ If you provide a one-way flow, then nothing would be sent back to the caller. In the case that you want to completely suppress Exceptions, you can provide a reference to the global "nullChannel" (essentially a /dev/null approach). Finally, as mentioned above, if no "error-channel" is defined at all, then the Exceptions will propagate as usual. +When using the `@MessagingGateway` annotation (see <>), use the `errroChannel` attribute. + Starting with _version 5.0_, when using a gateway method with a `void` return type (one-way flow), the `error-channel` reference (if provided) is populated in the standard `errorChannel` header of each message sent. This allows a downstream async flow, based on the standard `ExecutorChannel` configuration (or a `QueueChannel`), to override a default global `errorChannel` exceptions sending behavior. Previously you had to specify an `errorChannel` header manually via `@GatewayHeader` annotation or `
` sub-element.