camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bilgin Ibryam (Confluence)" <conflue...@apache.org>
Subject [CONF] Apache Camel > Try Catch Finally
Date Mon, 24 Jun 2013 10:33:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/en/2176/1/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CAMEL/Try+Catch+Finally">Try
Catch Finally</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~bibryam">Bilgin
Ibryam</a>
    </h4>
        <br/>
                         <h4>Changes (1)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >A third feature is that you can attach
a {{onWhen}} predicate to signal if the catch should trigger or not at runtime. <br>
<br></td></tr>
            <tr><td class="diff-changed-lines" >And to simulate <span class="diff-changed-words">_re<span
class="diff-added-chars"style="background-color: #dfd;">t</span>hrowing_</span>
an exception from a {{doCatch}} you should use the {{handled}} predicate. If its evaluated
to {{false}} Camel will reattach the exception on the [Exchange]. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h3. Using try .. catch
.. finally in Java DSL <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="TryCatchFinally-Try...Catch...Finally"></a>Try ...
Catch ... Finally</h2>
<p>Camel supports the Java equivalent of try .. catch and finally directly in the DSL.<br/>
It aims to work like its Java sisters but with more power. Especially in Camel 2.0 where we
gave this feature an overhaul.</p>

<p>In Camel we prefix the keywords with <tt>do</tt> to avoid having same
keyword as Java. So we have:</p>
<ul class="alternate" type="square">
	<li><tt>doTry</tt></li>
	<li><tt>doCatch</tt></li>
	<li><tt>doFinally</tt></li>
	<li><tt>end</tt> to end the block in Java DSL</li>
</ul>


<p>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.</p>

<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>Camel error
handling is disabled</b><br />When using <tt>doTry .. doCatch .. doFinally</tt>
then the regular Camel <a href="/confluence/display/CAMEL/Error+Handler" title="Error Handler">Error
Handler</a> does not apply. That means any <tt>onException</tt> or the likes
does not trigger. The reason is that <tt>doTry .. doCatch .. doFinally</tt> is
in fact its own error handler and that it aims to mimic and work like how try/catch/finally
works in Java.</td></tr></table></div>

<h3><a name="TryCatchFinally-About%7B%7BdoCatch%7D%7DanditspoweroverJava"></a>About
<tt>doCatch</tt> and its power over Java</h3>
<p>The <tt>doCatch</tt> in Camel is empowered over its Java sister.</p>

<p>First of all you can define multiple exceptions to catch in a single block.</p>

<p>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
<tt>doCatch</tt> 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.<br/>
Camel for instance does this by wrapped it in a <tt>CamelRuntimeException</tt>.
So if the original caused exception is an <tt>java.io.IOException</tt> then Camel
will still match a <tt>doCatch</tt> block defined with an <tt>java.io.IOException</tt>.
And just like Java the order in which you have multiple <tt>doCatch</tt> blocks
matter. Camel will iterate from the top going down and use the first <tt>doCatch</tt>
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 <a href="/confluence/display/CAMEL/Exception+Clause"
title="Exception Clause">Exception Clause</a> that has a more intelligent exception
selection strategy among multiple <tt>onException</tt> definitions, where it also
consider the delta in the exception hierarchy to select the best definition.</p>

<p>A third feature is that you can attach a <tt>onWhen</tt> predicate to
signal if the catch should trigger or not at runtime.</p>

<p>And to simulate <em>rethrowing</em> an exception from a <tt>doCatch</tt>
you should use the <tt>handled</tt> predicate. If its evaluated to <tt>false</tt>
Camel will reattach the exception on the <a href="/confluence/display/CAMEL/Exchange" title="Exchange">Exchange</a>.
</p>

<h3><a name="TryCatchFinally-Usingtry..catch..finallyinJavaDSL"></a>Using
try .. catch .. finally in Java DSL</h3>
<p>In the route below we have all keywords in action. As the code is based on a unit
test we route using <a href="/confluence/display/CAMEL/Mock" title="Mock">Mock</a>.</p>
<div class="error"><span class="error">Unknown macro: {code}</span> 
<p>from("direct:start")<br/>
    .doTry()<br/>
        .process(new ProcessorFail())<br/>
        .to("mock:result")<br/>
    .doCatch(IOException.class, IllegalStateException.class)<br/>
        .to("mock:catch")<br/>
    .doFinally()<br/>
        .to("mock:finally")<br/>
    .end();</p></div>

<p>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 <em>rethrow</em> the exception and this
is why we use <b>handled</b> and set it to false to indicate, no we did not handle
it so please keep the exception.<br/>
The 2nd exception block can be omitted but as the code is based on an unit test we want to
test the behavior non <tt>IOException</tt> as well.</p>
<div class="error"><span class="error">Unknown macro: {code}</span> 
<p>from("direct:start")<br/>
    // here is our try where we try processing the exchange in the route below if it fails<br/>
    // we can catch it below, just like regular try .. catch .. finally in Java<br/>
    .doTry()<br/>
        .process(new ProcessorFail())<br/>
        .to("mock:result")<br/>
    // catch IOExcption that we do not want to handle, eg the caller should get the error
back<br/>
    .doCatch(IOException.class)<br/>
        // mark this as NOT handled, eg the caller will also get the exception<br/>
        .handled(false)<br/>
        .to("mock:io")<br/>
    .doCatch(Exception.class)<br/>
        // and catch all other exceptions<br/>
        // they are handled by default (ie handled = true)<br/>
        .to("mock:error")<br/>
    // here the try block ends<br/>
    .end();</p></div>

<p>And finally we have an example of the <tt>onWhen</tt> predicate in action.
We can attach it to a <tt>doCatch</tt> block and at runtime determine if the block
should be triggered or not.<br/>
In our case we only want to trigger if the caused exception message contains the <b>damn</b>
word.</p>
<div class="error"><span class="error">Unknown macro: {code}</span> 
<p>from("direct:start")<br/>
    // here is our try where we try processing the exchange in the route below if it fails<br/>
    // we can catch it below, just like regular try .. catch .. finally in Java<br/>
    .doTry()<br/>
        .process(new ProcessorFail())<br/>
        .to("mock:result")<br/>
    // here we catch the following 2 exceptions but only if<br/>
    // the onWhen predicate matches, eg if the exception messsage<br/>
    // conatins the string word Damn<br/>
    .doCatch(IOException.class, IllegalStateException.class)<br/>
        .onWhen(exceptionMessage().contains("Damn"))<br/>
        .to("mock:catch")<br/>
    // another catch for CamelExchangeException that does not have any onWhen predicate<br/>
    .doCatch(CamelExchangeException.class)<br/>
        .to("mock:catchCamel")<br/>
    // and the finally that is always processed<br/>
    .doFinally()<br/>
        .to("mock:finally")<br/>
    // here the try block ends<br/>
    .end();</p></div>

<h3><a name="TryCatchFinally-Usingtry..catch..finallyinSpringDSL"></a>Using
try .. catch .. finally in Spring DSL</h3>
<p>We show the three sample samples using Spring DSL instead.</p>

<p>In the route below we have all keywords in action. As the code is based on a unit
test we route using <a href="/confluence/display/CAMEL/Mock" title="Mock">Mock</a>.</p>
<div class="error"><span class="error">Unknown macro: {code}</span> 
<p>&lt;route&gt;<br/>
    &lt;from uri="direct:start"/&gt;<br/>
    &lt;!-- here the try starts. its a try .. catch .. finally just as regular java code
--&gt;<br/>
    &lt;doTry&gt;<br/>
        &lt;process ref="processorFail"/&gt;<br/>
        &lt;to uri="mock:result"/&gt;<br/>
        &lt;doCatch&gt;<br/>
            &lt;!-- catch multiple exceptions --&gt;<br/>
            &lt;exception&gt;java.io.IOException&lt;/exception&gt;<br/>
            &lt;exception&gt;java.lang.IllegalStateException&lt;/exception&gt;<br/>
            &lt;to uri="mock:catch"/&gt;<br/>
        &lt;/doCatch&gt;<br/>
        &lt;doFinally&gt;<br/>
            &lt;to uri="mock:finally"/&gt;<br/>
        &lt;/doFinally&gt;<br/>
    &lt;/doTry&gt;<br/>
&lt;/route&gt;</p></div>

<p>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 <em>rethrow</em> the exception and this
is why we use <b>handled</b> and set it to false to indicate, no we did not handle
it so please keep the exception.<br/>
The 2nd exception block can be omitted but as the code is based on an unit test we want to
test the behavior non <tt>IOException</tt> as well.</p>
<div class="error"><span class="error">Unknown macro: {code}</span> 
<p>&lt;route&gt;<br/>
    &lt;from uri="direct:start"/&gt;<br/>
    &lt;!-- here the try starts. its a try .. catch .. finally just as regular java code
--&gt;<br/>
    &lt;doTry&gt;<br/>
        &lt;process ref="processorFail"/&gt;<br/>
        &lt;to uri="mock:result"/&gt;<br/>
        &lt;doCatch&gt;<br/>
            &lt;!-- catch IOExcption that we do not want to handle, eg the caller should
get the error back --&gt;<br/>
            &lt;exception&gt;java.io.IOException&lt;/exception&gt;<br/>
            &lt;!-- mark this as NOT handled, eg the caller will also get the exception
--&gt;<br/>
            &lt;handled&gt;<br/>
                &lt;constant&gt;false&lt;/constant&gt;<br/>
            &lt;/handled&gt;<br/>
            &lt;to uri="mock:io"/&gt;<br/>
        &lt;/doCatch&gt;<br/>
        &lt;doCatch&gt;<br/>
            &lt;!-- and catch all other exceptions they are handled by default (ie handled
= true) --&gt;<br/>
            &lt;exception&gt;java.lang.Exception&lt;/exception&gt;<br/>
            &lt;to uri="mock:error"/&gt;<br/>
        &lt;/doCatch&gt;<br/>
    &lt;/doTry&gt;<br/>
&lt;/route&gt;</p></div>

<p>And finally we have an example of the <tt>onWhen</tt> predicate in action.
We can attach it to a <tt>doCatch</tt> block and at runtime determine if the block
should be triggered or not.<br/>
In our case we only want to trigger if the caused exception message contains the <b>damn</b>
word.</p>
<div class="error"><span class="error">Unknown macro: {code}</span> 
<p>&lt;route&gt;<br/>
    &lt;from uri="direct:start"/&gt;<br/>
    &lt;!-- here the try starts. its a try .. catch .. finally just as regular java code
--&gt;<br/>
    &lt;doTry&gt;<br/>
        &lt;process ref="processorFail"/&gt;<br/>
        &lt;to uri="mock:result"/&gt;<br/>
        &lt;!-- here we catch the below 2 kind of exceptions but ONLY if the onWhen predicate
matches<br/>
             that means that the exception message should contain the string word 'Damn' --&gt;<br/>
        &lt;doCatch&gt;<br/>
            &lt;exception&gt;java.io.IOException&lt;/exception&gt;<br/>
            &lt;exception&gt;java.lang.IllegalStateException&lt;/exception&gt;<br/>
            &lt;onWhen&gt;<br/>
                &lt;simple&gt;$</p>
<div class="error"><span class="error">Unknown macro: {exception.message}</span>
</div>
<p> contains 'Damn'&lt;/simple&gt;<br/>
            &lt;/onWhen&gt;<br/>
            &lt;to uri="mock:catch"/&gt;<br/>
        &lt;/doCatch&gt;<br/>
        &lt;!-- we can have multiple catch blocks for different exception and with their
own onWhen --&gt;<br/>
        &lt;doCatch&gt;<br/>
            &lt;exception&gt;org.apache.camel.CamelExchangeException&lt;/exception&gt;<br/>
            &lt;to uri="mock:catchCamel"/&gt;<br/>
        &lt;/doCatch&gt;<br/>
        &lt;!-- the finally is always processed --&gt;<br/>
        &lt;doFinally&gt;<br/>
            &lt;to uri="mock:finally"/&gt;<br/>
        &lt;/doFinally&gt;<br/>
    &lt;/doTry&gt;<br/>
&lt;/route&gt;</p></div>

<h3><a name="TryCatchFinally-SeeAlso"></a>See Also</h3>
<ul class="alternate" type="square">
	<li><a href="/confluence/display/CAMEL/Error+handling+in+Camel" title="Error handling
in Camel">Error handling in Camel</a></li>
	<li><a href="/confluence/display/CAMEL/Error+Handler" title="Error Handler">Error
Handler</a></li>
	<li><a href="/confluence/display/CAMEL/Exception+Clause" title="Exception Clause">Exception
Clause</a></li>
</ul>


    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;" class="grey">
                        <a href="https://cwiki.apache.org/confluence/users/removespacenotification.action?spaceKey=CAMEL">Stop
watching space</a>
            <span style="padding: 0px 5px;">|</span>
                <a href="https://cwiki.apache.org/confluence/users/editmyemailsettings.action">Change
email notification preferences</a>
</div>
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Try+Catch+Finally">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=115281&revisedVersion=6&originalVersion=5">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Try+Catch+Finally?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message