Catching exceptions

Camel allows you to customize the handling of specific exceptions. Camel's exception matching is far more powerful than Java's in many ways, as it allows matching based on the inheritance tree of the exception. It lets you specify retry policies at the global, and more fine-grained route level.

This recipe will show you how to specify exception handlers for your routes.

Getting ready

The Java code for this recipe is located in the org.camelcookbook.error.exception package. The Spring XML files are located under src/main/resources/META-INF/spring and prefixed with exception.

How to do it...

Configure the onException DSL statement with a list of one or more exception class types to catch, and the associated processing actions to take in response.

In the XML DSL, define an onException element either within the camelContext or route element. Within the onException element, include one or more exception elements with the full package name of the exception that you want this handler to catch, and follow that with one or more route steps (for example, <to uri="direct:handleError"/>).

<camelContext xmlns="http://camel.apache.org/schema/spring">
  <onException>
    <exception>
      org.camelcookbook.error.shared.FlakyException
    </exception>
    <exception>
      org.camelcookbook.error.shared.SporadicException
    </exception>
    <to uri="mock:error"/>
  </onException>
  <!-- ... -->
</camelContext>

In the Java DSL, you define an onException block within RouteBuilder.configure() method, and include a comma separated list of one or more Exception class types that you want to handle. Then using the fluent API, define one or more routing steps that the exchange should flow through when that Exception type is matched (for example, to("direct:handleError")):

public class ExceptionRouteBuilder extends RouteBuilder {
  @Override
  public void configure() throws Exception {
    onException(FlakyException.class, SporadicException.class)
      .to("mock:error");

    from("direct:start") //...
  }
}

Note

You can define multiple onException blocks globally and within routes. Camel will evaluate matches based on the order you specify for the multiple onException handlers. That is, if you specify multiple exception handlers, Camel will evaluate them all for the best match. The order in which you specify them will also be considered in such a way that a handler defined first in the list will get preference over the next one in the list, all other things being equal.

How it works...

Camel uses a sophisticated algorithm for determining which exception handler will handle any given thrown exception. More details are available in the Camel Exception Handling documentation (http://camel.apache.org/exception-clause.html).

Camel will match based on several factors, some of which are listed in the following bullet list:

  • The order in which the exception handlers are specified, first to last, within the route, and then globally. Remember you can specify multiple handlers both within the route and globally.
  • The most deeply nested exception within the thrown exception is matched first, and then Camel will look for matches in the other wrapping exceptions.
  • The instanceof tests are performed to find the closest match based on the inheritance hierarchy of the exception. An exact match will always be used, and then the closest match.

This allows you to define some generic exception handlers globally, and then refine handling within a route based on a very specific exception being thrown.

By default, Camel's default exception handler will rethrow the exception to the caller. For route-specific exception handlers, this may mean the calling routes. For global exception handlers, the exception will be thrown to the consumer endpoint (for example, web service (SOAP/HTTP) listener) through which the message first entered the Camel context. The consumer will respond back to the caller in an endpoint-specific fashion. See the Marking exceptions as handled recipe, and the Catching exceptions recipe for more details on refining this behavior.

There's more...

You can also set route-specific onException handlers.

In the XML DSL, you define an onException handler definition right after the from element of your route:

<route>
  <from uri="direct:start"/>
  <onException>
    <exception>
      org.camelcookbook.error.shared.FlakyException
    </exception>
    <to uri="mock:error"/>
  </onException>
  <bean ref="flakyProcessor"/>
  <to uri="mock:result"/>
</route>

In the Java DSL, you define the route-specific onException handler in the same way as the global one, only you need to close out the handler's routing fragment with an .end() statement before your regular route steps. The route-specific onException handler is defined right after the from(…) statement:

from("direct:start")
    .onException(FlakyException.class)
      .to("mock:error")
    .end()
  .bean(FlakyProcessor.class)
  .to("mock:result");
..................Content has been hidden....................

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