Fine-grained error handling using doTry…doCatch

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.

Getting ready

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.

How to do it...

In the XML DSL, there are two mandatory steps and one optional steps needed for using doTry, which are as follows:

  1. Within a route, define a 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.
  2. Within the 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.
  3. After the 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:

  1. Specify a doTry() element followed by the one or more processing steps you wish to specify an exception handler.
  2. After the last processing step you wish to wrap, follow with a 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");

Tip

Remember to always finish your doTry exception handler with a call to end(), either after your last doCatch(…) or after the steps within your doFinally() block.

How it works...

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.

There's more...

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()

Note

Remember that by default doTry will consider an exception handled, that is, handled(true), which is different from the error and the onException handlers which default to handled(false).

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).

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.46.141