Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Once all attempts at redelivering the message fails then the message is forwarded to the dead letter queue.

Info

When the DeadLetterChannel moves a message to the dead letter endpoint, then if any new exceptions is thrown during that process, then by default the dead letter channel will handle the new exception as well. This ensures that the DeadLetterChannel will always succeed. From Camel 2.15 onwards this behavior can be changed by setting the option deadLetterHandleNewException=false. Then if a new exception is thrown, then the dead letter channel will fail and propagate back that new exception (which is the behavior of the default error handler).

 

About moving Exchange to dead letter queue and using handled

...

Using the Fluent Builders

Code Block
java
java

errorHandler(deadLetterChannel("jms:queue:dead")
    .maximumRedeliveries(3).redeliveryDelay(5000));

Using the Spring XML Extensions

Code Block
xml
xml

<route errorHandlerRef="myDeadLetterErrorHandler">
   ...
</route>

<bean id="myDeadLetterErrorHandler" class="org.apache.camel.builder.DeadLetterChannelBuilder">
    <property name="deadLetterUri" value="jms:queue:dead"/>
    <property name="redeliveryPolicy" ref="myRedeliveryPolicyConfig"/>
</bean>

<bean id="myRedeliveryPolicyConfig" class="org.apache.camel.processor.RedeliveryPolicy">
    <property name="maximumRedeliveries" value="3"/>
    <property name="redeliveryDelay" value="5000"/>
</bean>

...

For instance if you have this route:

Code Block

   from("jms:queue:order:input")
       .to("bean:validateOrder")
       .to("bean:transformOrder")
       .to("bean:handleOrder");

The route listen for JMS messages and validates, transforms and handle it. During this the Exchange payload is transformed/modified. So in case something goes wrong and we want to move the message to another JMS destination, then we can configure our Dead Letter Channel with the useOriginalMessage option. But when we move the Exchange to this destination we do not know in which state the message is in. Did the error happen in before the transformOrder or after? So to be sure we want to move the original input message we received from jms:queue:order:input. So we can do this by enabling the useOriginalMessage option as shown below:

Code Block
java
java

    // will use original body
    errorHandler(deadLetterChannel("jms:queue:dead")
       .useOriginalMessage().mamimumRedeliveries(5).redeliverDelay(5000);

...

When Camel routes messages it will decorate the Exchange with a property that contains the last endpoint Camel send the Exchange to:

Code Block

String lastEndpointUri = exchange.getProperty(Exchange.TO_ENDPOINT, String.class);

...

When for example processing the Exchange at a given Endpoint and the message is to be moved into the dead letter queue, then Camel also decorates the Exchange with another property that contains that last endpoint:

Code Block

String failedEndpointUri = exchange.getProperty(Exchange.FAILURE_ENDPOINT, String.class);

...

Notice: These information is kept on the Exchange even if the message was successfully processed by a given endpoint, and then later fails for example in a local Bean processing instead. So beware that this is a hint that helps pinpoint errors.

Code Block

from("activemq:queue:foo")
    .to("http://someserver/somepath")
    .beanRef("foo");

...

When Camel error handler handles an error such as Dead Letter Channel or using Exception Clause with handled=true, then Camel will decorate
the Exchange with the route id where the error occurred.

Code Block

String failedRouteId = exchange.getProperty(Exchange.FAILURE_ROUTE_ID, String.class);

...

Wiki Markup
{snippet:id=e2|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelOnRedeliveryTest.java}

Include Page
Using This Pattern
Using This Pattern