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>







