Error handling in Camel
Error handling in Camel can roughly be separated into two distinct types:
Where non transactional is the most common type that is enabled out-of-the-box and handled by Camel itself. The transaction type is handled by a backing system such as a J2EE application server.
Using try ... catch ... finally
Related to error handling is the Try Catch Finally feature in Camel.
When does an error happen
An error happens when
By default Camel uses the non transaction type and orchestrates the error handling during processing and routing.
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 1.x default error handler
Dead Letter Queue (*)
A dead letter queue is like a black hole, it will consume the Exchange and the Exchange routing is ended with no indication that it failed.
This default does not go well with other transports using in a request/reply messaging style. If the Exchange failed then the original caller want to be alter it failed.
So the bottom line is that you must configure and setup the error handling strategies that suits your business needs.
Camel 2.0 onwards default error handler
Camel supports 2 scopes that is determined by the DSL in use:
When using XML DSL then scope 1 applies for all routes. Where as when using Java DSL then route 1 only applies for the given RouteBuilder instance. So if you have multiple RouteBuilder's then each route builder has its own scope 1.
If you want to share scope among RouteBuilder's you can use class inheritance and create a base class, and then extend this class for your RouteBuilder's and invoke the super.configure() method.
Mind that there was a bug in Camel that affected the scopes when using multiple RouteBuilder classes. See more details at CAMEL-5456.
How does the Dead Letter Channel error handler work
When Camel is started it will inspect the routes and weave in the error handling into the routing. With up to 3 supported scopes, the error handling can be quite complex. And on top of that you have inherited error handling and you can even configure Exception Clauses 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 can 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.
An example illustrating this:
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 Dead Letter Channel that decides what to do next. Either it does a:
It will continue to do redeliveries based on the policy configured. By default Dead Letter Channel 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 transactions. 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.
How does it work
See Transactional Client for more.