Logging camel exceptions and sending to the dead letter channel

14,713

Solution 1

You can just use a route for the dead letter queue, and do logging and sending to JMS queue. And then use direct to refer to this route

<property name="deadLetterUri" value="direct:myDLC"/>

<route>
  <from uri="direct:myDLC"/>
  <log logName="notifications" loggingLevel="ERROR"
            message="Exception from notification Camel route" />
  <to uri="activemq:dead.letter.queue"/>
</route>

What version of Camel are you using?

Solution 2

Here is another option to log an exception and send exchange to dead letter queue, expressed in Camel DSL

Processor exceptionLoggingProcessor = (exchange) -> 
      logger.error("Error handled in camel.", exchange.getProperty(Exchange.EXCEPTION_CAUGHT));

setErrorHandlerBuilder(deadLetterChannel("direct:dlq")
    .onExceptionOccurred(exceptionLoggingProcessor));
Share:
14,713
Jeremy Gooch
Author by

Jeremy Gooch

Guitarist and IT architect

Updated on July 25, 2022

Comments

  • Jeremy Gooch
    Jeremy Gooch almost 2 years

    I have a Camel route, running within Karaf, for which I've added a Dead Letter Channel. This is to handle cases where the route fails and I want to keep the problem message and log the cause. I can't throw the exception back to the calling application as I'm handling some processing asynchronously.

    From reading the documentation and trying a number of cases, it's not clear to me how to both log the exception into Karaf's log and deposit the original message onto the dead letter queue.

    Here's an excerpt of what I've got:-

    <bean id="deadLetterQueue" class="org.apache.camel.builder.DeadLetterChannelBuilder">
        <property name="deadLetterUri" value="activemq:dead.letter.queue"/>
        <property name="redeliveryPolicy" ref="redeliveryPolicy"/>
    </bean>
    
    <bean id="redeliveryPolicy" class="org.apache.camel.processor.RedeliveryPolicy">
        <property name="maximumRedeliveries" value="1"/>
        <property name="redeliveryDelay" value="1000"/>
    </bean>
    
    <camelContext id="notification" errorHandlerRef="deadLetterQueue"
        trace="false" xmlns="http://camel.apache.org/schema/blueprint">
        <onException>
            <exception>org.xyz.exceptions.unchecked.notificationException</exception>
            <log logName="notifications" loggingLevel="ERROR"
                message="Exception from notification Camel route" />
        </onException>
    
        <route id="DoSomething" errorHandlerRef="deadLetterQueue">
            <from uri="activemq:notification.in" />
            <log logName="notifications" loggingLevel="TRACE"
                message="Notification route initiated" />
            <bean ref="NotificationProcessor" method="doStuff" />
        </route>
    </camelContext>
    

    If I remove the "onException" structure then, in all exception cases, the source message appears on the dead letter queue but isn't logged.

    If I run it as above then the exception trace is logged into Karaf's log (if it is a "notificationException") but the associated source message is not rolled back to the dead letter queue and disappears into the ether (presumably as it thinks I've handled it within the "onException" structure).

    Having looked at the different sorts of error handlers, I tried instead adding things to the DeadLetterChannelBuilder such as...

    <property name="logName" value="notifications"/>
    <property name="level" value="ERROR"/>
    

    ...but these aren't legal properties.

    It also strikes me that having to list the different exceptions explicitly in the onException clause can't be correct.

    So, how do I get the dead letter channel to log the exception trace as well as putting the message onto the queue? Perhaps the dead letter channel isn't the correct handler - I'm not really interested in automatic redelivery in this case.

    Thanks for any guidance,

    J.

  • Jeremy Gooch
    Jeremy Gooch over 11 years
    Thanks for the reply. I thought there would be a simple workaround. I need to get my head into Camel-mode-of-thinking! Do I need to add something to the log step to get it to output the exception or does the mere presence of a log step mean that any exception on the exchange will be thrown out into the log file? We're using 2.10.2.
  • Claus Ibsen
    Claus Ibsen over 11 years
    About the log then there is 2 different. Read the Camel docs at: camel.apache.org/log and camel.apache.org/logeip.html