You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 11 Next »

Exception Clause

You can use the Exception Clause in the Java DSL to specify the error handling you require on a per type basis using the exception() method.

For example if you want to perform a specific piece of processing if a certain exception is raised you can do this simply via

exception(ValidationException.class).
  to("activemq:validationFailed");
  
from("seda:inputA").
  to("validation:foo/bar.xsd", "activemq:someQueue");

from("seda:inputB").to("direct:foo").
  to("rnc:mySchema.rnc", "activemq:anotherQueue");

Here if the processing of seda:inputA or seda:inputB cause a ValidationException to be thrown (such as due to the XSD validation of the Validation component or the Relax NG Compact syntax validation of the Jing component), then the message will be sent to activemq:validationFailed queue.

Changes in Camel 1.5

In Camel 1.5 the exception clauses has been renamed to onException and it also supports multiple exception classes:

onException(MyBusinessException.class, MyOtherBusinessException.class).
  to("activemq:businessFailed");

But the most important new feature is support for marking exceptions as being handled.

Marking exceptions as being handled

Available as of Camel 1.5

Using onException to handle known exceptions is a very powerful feature in Camel. However prior to Camel 1.5 you could not mark the exception as being handled, so the caller would still receive the caused exception as a response. In Camel 1.5 you can now change this behavior with the new handle DSL. The handle is a Predicate that is overloaded to accept three types of parameters:

  • Boolean
  • Predicate
  • Expression that will be evaluates as a Predicate using this rule set: If the expressions returns a Boolean its used directly. For any other response its regarded as true if the response is not null.

For instance to mark all ValidationException as being handled we can do this:

  onException(ValidationException).handled(true);

Example using handled

In this route below we want to do special handling of all OrderFailedException as we want to return a customized response to the caller. First we setup our routing as:

Error formatting macro: snippet: java.lang.NullPointerException

Then we have our service beans that is just plain POJO demonstrating how you can use Bean Integration in Camel to avoid being tied to the Camel API:

Error formatting macro: snippet: java.lang.NullPointerException

And finally the exception that is being thrown is just a regular exception:

Error formatting macro: snippet: java.lang.NullPointerException

So what happens?

If we sent an order that is being processed OK then the caller will receive an Exchange as reply containing Order OK as the payload and orderid=123 in a header.

If the order could not be processed and thus an OrderFailedException was thrown the caller will not receive this exception (as opposed to in Camel 1.4, where the caller received the OrderFailedException) but our customized response that we have fabricated in the orderFailed method in our OrderService. So the caller receives an Exchange with the payload Order ERROR and a orderid=failed in a header.

Using handled with Spring DSL

The same route as above in Spring DSL:

Error formatting macro: snippet: java.lang.NullPointerException

Overloading the RedeliveryPolicy

The default error handler used in Camel is the Dead Letter Channel which supports attempting to redeliver the message exchange a number of times before sending it to a dead letter endpoint. Sometimes you want to overload the redelivery policy on a per exception type basis. By default in the above examples, if a ValidationException occurs then the message will not be redelivered; however if some other exception occurs (such as a JDBC deadlock or remote method invocation) the route will be retried.

However if you want to customize any methods on the RedeliveryPolicy object, you can do this via the fluent API...

onException(MyException.class).
  maximumRedeliveries(2);

You can mix and match these approaches; specifying a custom processor to be used after all the redeliveries fail together with customizing any aspect of the RedeliveryPolicy

And the spring DSL:

<onException>
   <exception>com.mycompany.MyException</exception>
   <redelivyPolicy maximumRedeliveries="2"/>
</onException>

Defining multiple exceptions

You can define multiple exceptions in the clause as:

onException(MyException.class, MyOtherException.class).
  maximumRedeliveries(2);

And in Spring DSL you just add another exception element:

<onException>
   <exception>com.mycompany.MyException</exception>
   <exception>com.mycompany.MyOtherException</exception>
   <redelivyPolicy maximumRedeliveries="2"/>
</onException>

Reusing ReliveryPolicy

Available as of Camel 1.5.1 or later
You can reference a RedeliveryPolicy so you can reuse existing configurations and use standard spring bean style configuration that supports property placeholders.

    <bean id="myRedeliveryPolicy" class="org.apache.camel.processor.RedeliveryPolicy">
        <property name="maximumRedeliveries" value="${myprop.max}"/>
    </bean>

     <onException>
         <!-- you can define multiple exceptions just adding more exception elements as show below -->
         <exception>com.mycompany.MyFirstException</exception>
         <exception>com.mycompany.MySecondException</exception>

         <!-- here we reference our redelivy policy defined above -->
         <redeliveryPolicy ref="myRedeliveryPolicy"/>
     </onException>

See also

The Error Handler for the general error handling documentation
The Dead Letter Channel for further details.
The Transactional Client for transactional behavior

  • No labels