Camel supports an equivalent to Java's try…catch…finally exception handling that provides the finest grained error handling within Camel, in that you can specify exception handling specific to one or more route processing steps. Camel provides a doTry…doCatch…doFinally set of declarations that mirror Java's try…catch error handling.
This recipe will show you how to use the doTry
DSL statement.
The Java code for this recipe is located in the org.camelcookbook.error.dotry
package. The Spring XML files are located under src/main/resources/META-INF/spring
and prefixed with dotry
.
In the XML DSL, there are two mandatory steps and one optional steps needed for using doTry
, which are as follows:
doTry
element for wrapping one or more processing steps for which you want to provide specific error handling. This must be after the from
element as doTry
cannot handle errors thrown from the consuming endpoint.doTry
element, you can nest one or more doCatch
elements. Each doCatch
element can specify one or more exception
elements with a value of the fully qualified Java class name of the exceptions you wish for it to handle. After the exception
elements, you can specify one or more routing steps as part of your handler.doCatch
element(s), and still nested within the doTry
element, you can optionally define a doFinally
element, that like the Java equivalent will always be called when either the steps in the doTry
element successfully complete, or after the steps within any triggered doCatch
exception handler, or after an uncaught (no matching doCatch
) exception is thrown.<route> <from uri="direct:start"/> <to uri="mock:before"/> <doTry> <bean ref="flakyProcessor"/> <transform> <constant>Made it!</constant> </transform> <doCatch> <exception> org.camelcookbook.error.shared.FlakyException </exception> <to uri="mock:error"/> <transform> <constant>Something Bad Happened!</constant> </transform> </doCatch> <doFinally> <to uri="mock:finally"/> </doFinally> </doTry> <to uri="mock:after"/> </route>
To implement the same logic through the Java DSL, perform the following steps within a route at some point after the from(…)
statement:
doTry()
element followed by the one or more processing steps you wish to specify an exception handler.doCatch(<list of exception class types>)
element. After the doCatch(…)
element, you define the exception processing steps to perform for the list of exceptions you provided in the doCatch(…) call. You can define multiple doCatch(…)
blocks.You can optionally follow your one or more doCatch(…)
blocks with a doFinally()
statement, which will be always be called regardless of how the message is leaving the doTry()
block.
from("direct:start") .to("mock:before") .doTry() .bean(FlakyProcessor.class) .transform(constant("Made it!")) .doCatch(FlakyException.class) .to("mock:error") .transform(constant("Something Bad Happened!")) .doFinally() .to("mock:finally") .end() .to("mock:after");
The doTry
exception handler is functionally similar to how Java's try…catch construct works. By default, the exception is considered as handled, which is different from the default behavior of Camel's onException
handler (see the Catching exceptions recipe).
The doTry
exception handler overrides other defined onException
and error handlers, as Camel does its best to mimic Java's behavior.
If you want the doTry
handler not to mark a processed exception as handled (that is re-throw the exception to the caller), you can set the handled
statement to false
. This will cause the doTry
handler to behave in the same way as an onException
block.
In the XML DSL, after the exception
element(s) specify a handled
element with a nested predicate:
<doCatch> <exception> org.camelcookbook.error.shared.FlakyException </exception> <handled> <constant>false</constant> </handled> <to uri="mock:error"/> </doCatch>
In the Java DSL, after the doCatch(…)
call, use the handled(…)
statement with either a boolean
or a predicate:
.doCatch(FlakyException.class)
.handled(false)
.to("mock:error")
.end()
If you want to make your doTry
handler have conditional doCatch
blocks, you can specify an onWhen
block with a predicate just like with the other error and onException
handlers (see the Conditional retry recipe).
3.129.194.106