blob: 2dc011d1b1460d29c2ac7f643d06471d6e47d05e [file] [log] [blame]
[[TryCatchFinally-TryCatchFinally]]
=== Try ... Catch ... Finally
Camel supports the Java equivalent of try .. catch and finally directly
in the DSL.
It aims to work like its Java sisters but with more power. Especially in
Camel 2.0 where we gave this feature an overhaul.
In Camel we prefix the keywords with `do` to avoid having same keyword
as Java. So we have:
* `doTry`
* `doCatch`
* `doFinally`
* `end` to end the block in Java DSL
Notice this document is based on how it works in Camel 2.0. In Camel 1.x
this feature isn't as powerful and it uses a slight different keyword
names.
===== Camel error handling is disabled
When using `doTry .. doCatch .. doFinally` then the regular Camel
link:error-handler.adoc[Error Handler] does not apply. That means any
`onException` or the likes does not trigger. The reason is that
`doTry .. doCatch .. doFinally` is in fact its own error handler and
that it aims to mimic and work like how try/catch/finally works in Java.
[[TryCatchFinally-AboutdoCatchanditspoweroverJava]]
==== About `doCatch` and its power over Java
The `doCatch` in Camel is empowered over its Java sister.
First of all you can define multiple exceptions to catch in a single
block.
And second of all an important aspect over the regular Java counter
parts is that Camel will check in the exception hierarchy when it
matches a thrown exception against the `doCatch` blocks. The reasons is
that many times the original caused exceptions is wrapped by other
wrapper exceptions, typically transposing the exception from a checked
to a runtime exception.
Camel for instance does this by wrapped it in a `CamelRuntimeException`.
So if the original caused exception is an `java.io.IOException` then
Camel will still match a `doCatch` block defined with an
`java.io.IOException`. And just like Java the order in which you have
multiple `doCatch` blocks matter. Camel will iterate from the top going
down and use the first `doCatch` that matches the exception. The reason
is to keep it similar to the regular java and how it selects a catch
block. This differers from the link:exception-clause.adoc[Exception
Clause] that has a more intelligent exception selection strategy among
multiple `onException` definitions, where it also consider the delta in
the exception hierarchy to select the best definition.
A third feature is that you can attach a `onWhen` predicate to signal if
the catch should trigger or not at runtime.
And to simulate _rethrowing_ an exception from a `doCatch` you should
use the `handled` predicate. If its evaluated to `false` Camel will
reattach the exception on the link:exchange.adoc[Exchange].
[[TryCatchFinally-UsingtrycatchfinallyinJavaDSL]]
==== Using try .. catch .. finally in Java DSL
In the route below we have all keywords in action. As the code is based
on a unit test we route using <<mock-component,Mock>>.
https://github.com/apache/camel/tree/master/camel-core/src/test/java/org/apache/camel/processor/TryProcessorMultipleExceptionTest.java[TryProcessorMultipleExceptionTest.java]
And in the route below we want to indicate if an IOException occured we
want to route it elsewhere and at the same time keep the exception so
the original caller is notified about this exception. To do this we need
to not _rethrow_ the exception and this is why we use *handled* and set
it to false to indicate, no we did not handle it so please keep the
exception.
The 2nd exception block can be omitted but as the code is based on an
unit test we want to test the behavior non `IOException` as well.
https://github.com/apache/camel/tree/master/camel-core/src/test/java/org/apache/camel/processor/TryProcessorHandledTest.java[TryProcessorHandledTest.java]
And finally we have an example of the `onWhen` predicate in action. We
can attach it to a `doCatch` block and at runtime determine if the block
should be triggered or not.
In our case we only want to trigger if the caused exception message
contains the *damn* word.
https://github.com/apache/camel/tree/master/camel-core/src/test/java/org/apache/camel/processor/TryProcessorOnWhenTest.java[TryProcessorOnWhenTest.java]
===== Use end() to end the block
Notice when using Java DSL we must use `end()` to indicate where the try
.. catch .. finally block ends. As the example above has a finally, then
the `end()` should be at the end of the finally block. If we are not
using a finally, then the `end()` should be at the end of the `doCatch`
to indicate the end there.
[[TryCatchFinally-Usingtry..catch..finallyinSpringDSL]]
Using try .. catch .. finally in Spring DSL
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
We show the three sample samples using Spring DSL instead.
In the route below we have all keywords in action. As the code is based
on a unit test we route using <<mock-component,Mock>>.
https://github.com/apache/camel/tree/master/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringTryProcessorMultipleExceptionTest.xml[SpringTryProcessorMultipleExceptionTest.xml]
And in the route below we want to indicate if an IOException occured we
want to route it elsewhere and at the same time keep the exception so
the original caller is notified about this exception. To do this we need
to not _rethrow_ the exception and this is why we use *handled* and set
it to false to indicate, no we did not handle it so please keep the
exception.
The 2nd exception block can be omitted but as the code is based on an
unit test we want to test the behavior non `IOException` as well.
https://github.com/apache/camel/tree/master/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringTryProcessorHandledTest.xml[SpringTryProcessorHandledTest.xml]
And finally we have an example of the `onWhen` predicate in action. We
can attach it to a `doCatch` block and at runtime determine if the block
should be triggered or not.
In our case we only want to trigger if the caused exception message
contains the *damn* word.
https://github.com/apache/camel/tree/master/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringTryProcessorOnWhenTest.xml[SpringTryProcessorOnWhenTest.xml]
[[TryCatchFinally-SeeAlso]]
==== See Also
* link:error-handling-in-camel.adoc[Error handling in Camel]
* link:error-handler.adoc[Error Handler]
* link:exception-clause.adoc[Exception Clause]