Abhishek Singh
Abhishek Singh

Reputation: 295

catch exception in camel

I have a route in camel which is as follows

errorHandler(deadLetterChannel("file:somelocation");

            from("jms:queuwlocation").to(
                    "file:someLocation");

I have read that camel error handling comes when there's a processing between two nodes, such as Processor, Predicate etc. But what if I cannot consume the message, in my case the camel cannot connect to jms. How should I log this exception ?. As I am trying to use a deadLetterChannel to send the message to filesystem, but since I have not received the message there is nothing new on the file location. how should I encounter this type of situation?

Upvotes: 0

Views: 1693

Answers (2)

Fritz Duchardt
Fritz Duchardt

Reputation: 11870

The problem you are facing might be due to the JMS Connection Exception being thrown outside of the life cycle of your Camel exchange. Claus Ibsen refers this in "Camel in Action" as a chicken and egg situation:

You can picture this as a chicken and egg situation. Camel's error handler only applies during routing of Exchanges (chicken), but the consumer needs successfully to create the Exchange (hatch the egg). So if we want a chicken but only have an egg, what can we do?

The answer lies with extending the error handling boundaries to cover the entire Camel JMS Consumer:

As a figure of speech we can tell Camel to treat the eggs as if they were chickens. This is done by configuring the consumer to bridge its internal error handler with Camel's error handler.

For the JMS module, I suspect this involves playing around with the transferException property. Good luck with that!

Futhermore, I don't think using a deadletter channel is appropriate for your problem, since you don't gain anything from taking messages out of the queue when encountering a connectivity problem.

Typically connectivity problems are self fixing, e.g. a server was restarted, and can be solved by retrial. For your use case, a sensible redelivery strategy can do this. Luckily Camel is really good at this: https://camel.apache.org/redeliverypolicy.html.

I recommend an indefinite redelivery until connectivity commences. Something like this:

        onException(SomeJmsTimeoutException.class, SomeJmsConnectivityException.class)
            .useOriginalMessage()
            .maximumRedeliveries(Integer.MAX_VALUE)
            .retryAttemptedLogLevel(LoggingLevel.ERROR)
            .logRetryStackTrace(true)
            .redeliveryDelay(1000 * 60);

Upvotes: 1

Souciance Eqdam Rashti
Souciance Eqdam Rashti

Reputation: 3191

As far as I know the error handling does not come in play just between the nodes. It has a more complete scope than that. It also depends on the type of error you are facing.

How you should log the exception?

Well why don't you do it like this?

  1. DeadLetterChannel defined and you refer to it on your CamelContext.
  2. The deadletteruri refers to another route - call it errorhandler route.
  3. In the errorhandler route you can set headers that contain errors and other information you want to set.
  4. In the errorhandler route in your "to" send the error message to a file writing the headers with it like you would with a log file.

Upvotes: 0

Related Questions