Error handling in Camel has been edited by Claus Ibsen (Jan 03, 2009).

(View changes)

Content:

Error handling in Camel

Error handling in Camel can roughly be separated into two distinct types:

  • non transactional
  • transactional

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.

When does an error happen

An error happens when

  • any uncaught exception is thrown during routing and processing of messages within Camel

    So think this is a big exception interceptor that catches all exceptions and orchestrates what to do.

Non transactional

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:

  • redeliver up till 6 times
  • pause 1 sec between each redelivery attempt
  • if all redelivery attempts failed then move exchange into the dead letter queue
  • the default dead letter queue is a logger that logs the exchange at ERROR level

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.

Scopes

Camel supports 2 scopes for the non transactional type:

  • global
  • per route

And 3 scopes for transactional type:

  • global
  • per route
  • per policy (spring transaction policy)

How does it work

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.

Snapshot based

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. Before the Exchange is being allowed to pass to the next node a snapshot of it is taken as a copy, and stored in the error handler. If the exchange could be routed without any problems then it's forwarded to the next node in the route graph, that yet again is wrapped by the Error Handler that does the AOP around stuff. But if there was an exception thrown, then the Error Handler kicks in and decides what to do. If it redeliver then it will use a copy of the original snapshot to ensure the exchange is exactly the same as before. The same applies if the exchange could not be redelivered and it should be moved into the dead letter queue. Then it's also the original exchange that is used plus the exception that caused this error is also set on the exchange. So Camel will only redeliver the last part of the route that failed.

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. But before we send it the Error Handler will take a snapshot of the Exchange. In case the validation bean processed ok, we move on to the next node.
Again the Error Handler will take a copy of the Exchange before invoking the storeOrder bean. In case the storeOrder failed and throws an exception it's caught by the AOP around stuff and Camel will decide what to do. If we do a redeliver attempt we use the snapshot that we took the first time. So if the store order bean did alter anything in the exchange in the first try, these changes is gone and we have an fresh copy of the original exchange. That is basically it.

This applies to all kind of Components in Camel. The sample above only uses Bean but it's the same for File, Mail, Velocity or whatever component you use.

Transactional

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.

How does it work

Camel does the same as weaving for non both types. The difference is that transactional is not snapshot based and 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.

See also

Reply via email to