Dead Letter Channel – handling errors later

Camel's Dead Letter Channel error handler helps when you want to send generic errors to a particular endpoint. It can also be useful if you just want to capture the message that caused the error for manual processing later.

This technique allows you to send the Exchange instance that caused the error to a specific Camel endpoint (for example, activemq:queue:somethingBadHappenedQueue), or to send the message to another route (for example, seda:error). Remember that for Camel, an endpoint URI can refer to either another Camel route (the URI within the from(…) element), or it can be a producer endpoint (sends a message somewhere), for example activemq:queue:errorQueue.

Dead Letter Channel – handling errors later

This recipe will show you how to use Camel's Dead Letter Channel error handler to send the exchange to another Camel route for processing.

Getting ready

The Java code for this recipe is located in the org.camelcookbook.error.dlc package. The Spring XML files are located under src/main/resources/META-INF/spring and prefixed with dlc.

How to do it...

In the XML DSL, define an errorHandler element within the camelContext element and reference its id with the errorHandlerRef attribute of the camelContext element. The type attribute of the errorHandler element must be set to "DeadLetterChannel". You then set the deadLetterUri attribute to the endpoint (or route) you would like to send the message that caused the exception.

The following code will set the base error handler for all routes defined within this Camel context:

<camelContext errorHandlerRef="dlcErrorHandler"
              xmlns="http://camel.apache.org/schema/spring">
  <errorHandler
      id="dlcErrorHandler"
      type="DeadLetterChannel"
      deadLetterUri="seda:error"/>

<route>
  <from uri="direct:start"/>
  <!-- ... -->
  </route>
<route id="myErrorHandlingRoute">
  <from uri="seda:error"/>
  <!-- … -->
</route>
</camelContext>

If using the Java DSL, within the RouteBuilder.configure() method, define an errorHandler instance that references a deadLetterChannel instance. The sole argument to deadLetterChannel is the endpoint URI to which you want to send the failed messages.

The following code will configure the base error handler for all routes defined within this RouteBuilder implementation:

public class DlcRouteBuilder extends RouteBuilder {
  @Override
  public void configure() throws Exception {
    errorHandler(deadLetterChannel("seda:error"));

    from("direct:start") //...

    from("seda:error") //...
  }
}

How it works...

When an error (Exception) occurs during the processing of a message, and if no exception handling blocks have handled that error (see the Catching exceptions section), the Dead Letter Channel error handler will be invoked. It will route the failed exchange to the endpoint whose URI you specified. This is a simple way to capture the message state at the time of failure, so you can have another system (or person) inspect the message and try to address the issue.

Sending the failed message to another route gives you an opportunity to inspect the exchange's headers and properties at the time for failure, to give you more insight into the issue. Camel sets some additional properties that can help you identify the problem, which you may want to keep with the message. For example, Camel sets the CamelToEndpoint property to the last endpoint URI that it sent the exchange to; and CamelFailureEndpoint to the URI of the endpoint that it thinks caused the failure.

There's more...

The default behavior of the DeadLetterChannel is to route the message as it was at the time of the error. However, on occasion you will want to see the original state of the message as it was when it entered a route, to make it easier to reinsert back into the original route. Camel includes a useOriginalMessage option that will have the DeadLetterChannel route the message as seen when it entered the route that failed, versus the message state at the point of failure. This is useful, as you may have altered the message state as a part of your message processing.

In the XML DSL, you set the useOriginalMessage attribute to true on the errorHandler element:

<camelContext errorHandlerRef="dlcErrorHandler"
              xmlns="http://camel.apache.org/schema/spring">
  <errorHandler id="dlcErrorHandler"
                type="DeadLetterChannel"
                deadLetterUri="seda:error"
                useOriginalMessage="true"/>
  //...
</camelContext>

In the Java DSL, the same thing is expressed as:

public class DlcRouteBuilder extends RouteBuilder {
  @Override
  public void configure() throws Exception {
    errorHandler(
      deadLetterChannel("seda:error")
        .useOriginalMessage()
    );
    //...
  }
}

You can also set route-specific error handlers if you want to handle errors from various routes differently.

In the XML DSL, you set the errorHandlerRef attribute on the route element:

<camelContext xmlns="http://camel.apache.org/schema/spring">
  <errorHandler id="myRouteHandler"
                type="DeadLetterChannel"
                deadLetterUri="seda:error"/>

  <route errorHandlerRef="myRouteHandler">
    <from uri="direct:start"/>
    <!-- ... -->
  </route>
</camelContext>

In the Java DSL, you specify a route-specific error handler after the from part of the route definition:

from("direct:start")
  .errorHandler(
    deadLetterChannel("seda:error")
      .useOriginalMessage()
  )
  .bean(FlakyProcessor.class)
  .to("mock:result");
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.2.240