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.
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
.
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") //... } }
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.
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:
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.
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");
18.218.238.134