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. Fuse Mediation Router 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 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 4.14).Conditional catching—you can catch an exception conditionally, by appending an
onWhensub-clause to thedoCatchclause (see Conditional exception catching using onWhen).
Example 4.14 shows a doTry
block 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.
Example 4.14. Catching exceptions with a try, catch, finally
<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>
To prevent the current exception from being rethrown and propagated back to the
consumer endpoint, you can add a handled element to the
doCatch clause. The handled
element can be a boolean or an expression. Any non-boolean expression is interpreted
as true if it evaluates to a non-null value.
You set the value for handled using the
Property Editor and setting the Handled
property. See Catch in Enterprise Integration Pattern Reference.
Example 4.15 rethrows the
IOException exception using the handled element.
Example 4.15. Rethrowing an exception in a doCatch
<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>
In Example 4.15, 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.
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. To conditionalize the
exceptions caught by a doCatch clause you use a
onWhen child. If you specify an
onWhen option in an doCatch
clause, a match is triggered only when the thrown exception matches the clause and the
onWhen predicate evaluates to true on the
current exchange.
For example, Example 4.16 will catch the
exceptions IOException and
IllegalStateException, only if the exception message
contains the word, Severe.
Example 4.16. Conditional exception catching
<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>








