Error handling in Camel can roughly be separated into two distinct types:
Where as non transactional is the most common type that is enabled out-of-the-box and orchestrated by Camel itself. Opposed to the transaction type that is orchestrated by a backing system such as a J2EE application server.
An error happens when
By Default Camel uses the non transaction type and orchestrates the error handling during processing and routing. By default Camel uses a global Dead Letter Channel as the Error Handler. It's configured as:
As there isn't a single error handling configuration that suites all uses cases, you should consider altering the default configurations to better suit you needs.
Camel supports 2 scopes for the non transactional type:
And 3 scopes for transactional type:
When Camel is started it will inspect the routing and weave in the error handling in the routing. As the error handling can be quite complex with up till 3 supported scopes it can be a bit complex. And on top of that you have inherited error handling and you can even configure Exception Clause to handle specific exception types differently. So yes it's advanced but very powerful when you get the grip of it.
To keep things simple we first look at the basic concept how Camel orchestrates the redelivery attempt. At any given node in the route graph Camel intercepts the current Exchange being routed and wraps it with the Error Handler. This ensures that the Error Handler can kick in, just as the AOP around concept. If the exchange could be routed without any problems then it's forwarded to the next node in the route graph, But if there was an exception thrown, then the Error Handler kicks in and decides what to do.
We need an example to illustrate this:
from("seda:newOrder") .to("bean:validateOrder") .to("bean:storeOrder") .to("bean:confirmOrder");
In this route we have 3 nodes (the dots) where the Error Handler is watching us (The AOP around stuff). So when an order arrives on the seda queue we consume it and send it to the validateOrder bean. In case the validation bean processed ok, we move on to the next node. In case the storeOrder bean failed and throws an exception it's caught by the Error Handler that decides what to do next. Either it does a:
It will continue to do redeliveries based on the policy configured. By default Camel will attempt at most 6 redeliveries with 1 second delay. So if the storeOrder bean did succeed at the 3rd attempt the routing will continue to the next node the confirmOrder bean. In case all redeliveries failed the Exchange is regarded as failed and is moved to the dead letter queue and the processing of this exchange stops. By default the dead letter queue is just a ERROR logger.
Camel leverages Spring transaction. Usually you can only use this with a limited number of transport types such as JMS or JDBC based, that yet again requires a transaction manager such as a Spring transaction, a J2EE server or a Message Broker.
Camel does the same as weaving for non both types. The difference is that for transactional exchanges the Error Handler does not kick in. You can say the AOP around does not apply. Camel relies solely on the backing system to orchestrate the error handling. And as such the when the backing system does redeliver it will start all over again. For instance if the exchanges was started by a JMS consumer then it's started again as the JMS messages is rolled back on the JMS queue and Camel will re consume the JMS message again.
See Transactional Client for more.