Reputation: 423
I'm trying to configure an exception handler for all exceptions thrown by all routes in my camel context. My approach is the following, with no luck:
At this point, exceptions thrown inside the routes defined in spring are handled by the DefaultErrorHandler, not the one I'm trying to define. Here's what my error handling route definition looks like
public class MyErrorHandlerRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
onException(Exception.class)
.routeId("errorHandlerRoute")
.handled(true)
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
Throwable caused = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class);
// do some custom processing of the exception
}
})
.stop();
}
What else can I try, or where am I going wrong?
Upvotes: 10
Views: 11268
Reputation: 909
After retrieving your XML routes as a Resource from an application context and loading them to the camel context you will have a RoutesDefinition object you can try to manipulate like
Resource xmlRoutes = applicationContext.getResource("path/to/xml/routes");
RoutesDefinition routeDefinitions = camelContext.loadRoutesDefinition(xmlRoute.getInputStream());
for (RouteDefinition routeDefinition : routeDefinitions.getRoutes()) {
routeDefinition
.onException(Exception.class)
.handled(true)
// do some custom processing of the exception
Upvotes: 0
Reputation: 418
For future readers, this is the solution that I use for camel error handling (This is all java config but it will work as spring xml):
DeadLetterChannelBuilder
Bean@Bean
public DeadLetterChannelBuilder myErrorHandler() {
DeadLetterChannelBuilder deadLetterChannelBuilder = new DeadLetterChannelBuilder();
deadLetterChannelBuilder.setDeadLetterUri("direct:error");
deadLetterChannelBuilder.setRedeliveryPolicy(new RedeliveryPolicy().disableRedelivery());
deadLetterChannelBuilder.useOriginalMessage();
return deadLetterChannelBuilder;
}
Now this bean will be responsible for picking up errors and directing them to the direct:error
URI.
You will want a route to listen on the URI direct:error
because this is where your errors are now being routed.
@Override
public void configure() throws Exception {
from("direct:error")
.to("log:error")
.end();
}
As you can see now that all your errors are being routed to the above route you have the flexibility to implement complex error handling logic globally.
You still need to inject your error handling bean into each route. I wish camel would handle this automatically but I have not found a way. Although with this approach the code duplication/overhead is minimal.
@Override
public void configure() throws Exception {
errorHandler(myErrorHandler)
from("myStartingUri")
.to("myEndDestination")
.end();
}
Looking at the documentation for springs xml based config I think you would need to put <route errorHandlerRef="myErrorHandler">
in your route definition.
Upvotes: 7
Reputation: 55540
Create an abstract base class and define your global error handler in the configure method. And then in your route classes extend this base class, and in their configure method call super.configure() first.
Upvotes: 7
Reputation: 22279
Error handlers are route builder specific in Java DSL. You need to create one per route builder. Or in your case, you need to define it in Spring DSL (as you seems to define your routes in Spring).
Upvotes: 1