To handle exceptions within a route, you can use a
combination of the doTry, doCatch,
and doFinally clauses, which handle exceptions
in a similar way to Java's try,
catch, and finally
blocks.
In general, the doCatch() clause in a route
definition behaves in an analogous way to the
catch() statement in Java code. In
particular, the following features are supported by the
doCatch() clause:
Multiple doCatch clauses—you can have multiple
doCatchclauses within a singledoTryblock. ThedoCatchclauses are tested in the order they appear, just like Javacatch()statements. Apache Camel executes the firstdoCatchclause that matches the thrown exception.![[Note]](imagesdb/note.gif)
Note This algorithm is different from the exception matching algorithm used by the
onExceptionclause—see onException Clause for details.Rethrowing exceptions—you can rethrow the current exception from within a
doCatchclause using thehandledsub-clause (see Rethrowing exceptions in doCatch).
There are some special features of the
doCatch() clause, however, that have no
analogue in the Java catch() statement. The
following features are specific to
doCatch():
Catching multiple exceptions—the
doCatchclause allows you to specify a list of exceptions to catch, in contrast to the Javacatch()statement, which catches only one exception (see Example).Conditional catching—you can catch an exception conditionally, by appending an
onWhensub-clause to thedoCatchclause (see Conditional exception catching using onWhen).
The following example shows how to write a
doTry block in the Java DSL, where the
doCatch() clause will be executed, if
either the IOException exception or the
IllegalStateException exception are raised,
and the doFinally() clause is
always executed, irrespective of
whether an exception is raised or not.
from("direct:start")
.doTry()
.process(new ProcessorFail())
.to("mock:result")
.doCatch(IOException.class, IllegalStateException.class)
.to("mock:catch")
.doFinally()
.to("mock:finally")
.end();Or equivalently, in Spring XML:
<route>
<from uri="direct:start"/>
<!-- here the try starts. its a try .. catch .. finally just as regular java code -->
<doTry>
<process ref="processorFail"/>
<to uri="mock:result"/>
<doCatch>
<!-- catch multiple exceptions -->
<exception>java.io.IOException</exception>
<exception>java.lang.IllegalStateException</exception>
<to uri="mock:catch"/>
</doCatch>
<doFinally>
<to uri="mock:finally"/>
</doFinally>
</doTry>
</route>It is possible to rethrow an exception in a
doCatch() clause by calling the
handled() sub-clause with its argument set
to false, as follows:
from("direct:start")
.doTry()
.process(new ProcessorFail())
.to("mock:result")
.doCatch(IOException.class)
// mark this as NOT handled, eg the caller will also get the exception
.handled(false)
.to("mock:io")
.doCatch(Exception.class)
// and catch all other exceptions
.to("mock:error")
.end();In the preceding example, if the IOException
is caught by doCatch(), the current exchange is
sent to the mock:io endpoint, and then the
IOException is rethrown. This gives the
consumer endpoint at the start of the route (in the
from() command) an opportunity to handle
the exception as well.
The following example shows how to define the same route in Spring XML:
<route>
<from uri="direct:start"/>
<doTry>
<process ref="processorFail"/>
<to uri="mock:result"/>
<doCatch>
<exception>java.io.IOException</exception>
<!-- mark this as NOT handled, eg the caller will also get the exception -->
<handled>
<constant>false</constant>
</handled>
<to uri="mock:io"/>
</doCatch>
<doCatch>
<!-- and catch all other exceptions they are handled by default (ie handled = true) -->
<exception>java.lang.Exception</exception>
<to uri="mock:error"/>
</doCatch>
</doTry>
</route>A special feature of the Apache Camel doCatch()
clause is that you can conditionalize the catching of
exceptions based on an expression that is evaluated at run
time. In other words, if you catch an exception using a
clause of the form,
doCatch(,
an exception will only be caught, if the predicate
expression, ExceptionList).doWhen(Expression)Expression, evaluates
to true at run time.
For example, the following doTry block will
catch the exceptions, IOException and
IllegalStateException, only if the
exception message contains the word,
Severe:
from("direct:start")
.doTry()
.process(new ProcessorFail())
.to("mock:result")
.doCatch(IOException.class, IllegalStateException.class)
.onWhen(exceptionMessage().contains("Severe"))
.to("mock:catch")
.doCatch(CamelExchangeException.class)
.to("mock:catchCamel")
.doFinally()
.to("mock:finally")
.end();Or equivalently, in Spring XML:
<route>
<from uri="direct:start"/>
<doTry>
<process ref="processorFail"/>
<to uri="mock:result"/>
<doCatch>
<exception>java.io.IOException</exception>
<exception>java.lang.IllegalStateException</exception>
<onWhen>
<simple>${exception.message} contains 'Severe'</simple>
</onWhen>
<to uri="mock:catch"/>
</doCatch>
<doCatch>
<exception>org.apache.camel.CamelExchangeException</exception>
<to uri="mock:catchCamel"/>
</doCatch>
<doFinally>
<to uri="mock:finally"/>
</doFinally>
</doTry>
</route>







