Do Try
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.
In Camel, we prefix the keywords with
do
to avoid having same keyword as Java.
So we have:
-
doTry -
doCatch -
doFinally -
endto end the block in Java DSL
|
When using
The reason is that
|
EIP options
The Do Try eip supports the following options which are listed below.
| Name | Description | Default | Type |
|---|---|---|---|
|
note |
The note for this node. |
String |
|
|
description |
The description for this node. |
String |
|
|
disabled |
Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime. |
false |
Boolean |
|
outputs |
Required |
List |
|
|
doCatch |
Catches exceptions as part of a try, catch, finally block. |
List |
|
|
doFinally |
Path traversed when a try, catch, finally block exits. |
FinallyDefinition |
Using doTry … doCatch … doFinally
In the route below we have all of them in action:
-
Java
-
XML
-
YAML
from("direct:start")
.doTry()
.process(new ProcessorFail())
.to("mock:result")
.doCatch(IOException.class, IllegalStateException.class)
.to("mock:catch")
.doFinally()
.to("mock:finally")
.end();
<route>
<from uri="direct:start"/>
<doTry>
<process ref="processorFail"/>
<to uri="mock:result"/>
<doCatch>
<exception>java.io.IOException</exception>
<exception>java.lang.IllegalStateException</exception>
<to uri="mock:catch"/>
</doCatch>
<doFinally>
<to uri="mock:finally"/>
</doFinally>
</doTry>
</route>
- route:
from:
uri: direct:start
steps:
- doTry:
steps:
- process:
ref: processorFail
- to:
uri: mock:result
- doCatch:
exception:
- java.io.IOException
- java.lang.IllegalStateException
steps:
- to:
uri: mock:catch
- doFinally:
steps:
- to:
uri: mock:finally
Using onWhen with doCatch
You can use
Predicates
with
doCatch
to make it determine at runtime if the block should be triggered or not.
In this example, we only want to trigger if the caused exception message contains the word
Damn
.
-
Java
-
XML
-
YAML
from("direct:start")
.doTry()
.process(new ProcessorFail())
.to("mock:result")
.doCatch(IOException.class, IllegalStateException.class)
.onWhen(exceptionMessage().contains("Damn"))
.to("mock:catch")
.doCatch(CamelExchangeException.class)
.to("mock:catchCamel")
.doFinally()
.to("mock:finally")
.end();
<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 'Damn'</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>
- route:
from:
uri: direct:start
steps:
- doTry:
steps:
- process:
ref: processorFail
- to:
uri: mock:result
- doCatch:
exception:
- java.io.IOException
- java.lang.IllegalStateException
steps:
- onWhen:
expression:
simple:
expression: "${exception.message} contains 'Damn'"
- to:
uri: mock:catch
- doCatch:
exception:
- org.apache.camel.CamelExchangeException
steps:
- to:
uri: mock:catchCamel
- doFinally:
steps:
- to:
uri: mock:finally
Use end() to end the block
When using Java DSL you must use
end()
to indicate where the try … catch … finally block ends.
If the route has a
doFinally
, then the
end()
should be at the end of the finally block.
If there is no
doFinally
, then the
end()
should be at the end of the last
doCatch
.
Instead of
end()
you can use
endDoTry()
to end and
return back
to the try … catch scope.
|
Nested doTry … doCatch
When nesting
doTry … doCatch
from an outer
doTry … doCatch
EIP,
pay extra attention when using Java DSL as the Java programming language is not
indent aware
so you may write code that is indented in a way where you think a catch block is associated with the other doTry, but it is not.
Given the following Java DSL:
from("direct:test")
.doTry().
doTry().
throwException(new IllegalArgumentException("Forced by me"))
.doCatch(Exception.class)
.log("docatch 1")
.throwException(new IllegalArgumentException("Second forced by me"))
.doCatch(Exception.class)
.log("docatch 2")
.end();
Both
docatch 1
and
docatch 2
are in the inner
doTry
, and the outer
doTry
has no catch blocks.
Use
endDoTry()
to end the blocks correctly:
from("direct:test")
.doTry().
doTry().
throwException(new IllegalArgumentException("Forced by me"))
.doCatch(Exception.class)
.log("docatch 1")
.throwException(new IllegalArgumentException("Second forced by me"))
.endDoTry() // end this doCatch block
.endDoTry() // end the inner doTry
.doCatch(Exception.class)
.log("docatch 2")
.end();