Camel Exception handling doesnt work if exception clause is defined in a separate class

丶灬走出姿态 提交于 2019-11-30 03:30:57

问题


I am trying to build a application with several camel routes which re use many common routes internally. Hence, I am trying to segregate the routes in several different Route Builder classes and then connecting the routes where needed.

For eg, all routes pertaining to sending emails go into a EmailRouteBuilder class and all routes dealing with a particular JMS Queue go into MyQueueRouteBuilder class. I suppose this should be alright since Camel doesnt not distinguish between classes and only looks for routes defininition.

In addition, I am also grouping several exception handling routes into a separate ExceptionHandlingRouteBuilder.

I am also connecting all the different classes together by defining the camel context in Spring like so -

<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
    <propertyPlaceholder id="properties" location="classpath:${env}/autoimport.properties"/>
    <!-- Common Routes -->
    <routeBuilder ref="emailRouteBuilder" />
    <routeBuilder ref="myQueueRouteBuilder" />
  <routeBuilder ref="httpRouteBuilder" />
    <routeBuilder ref="exceptionsRouteBuilder" />
    <routeBuilder ref="customer1RouteBuilder" />
    <routeBuilder ref="customer2RouteBuilder" />

</camelContext>

My exceptionsRouteBuilder contains many exception clauses like -

onException(ConnectException.class)
            .routeId("connectExceptionEP")
            .handled(true)
            .log("Caught Exception: ")
            .to("direct:gracefulExit");

..
..
..

However, it looks like there is a problem with the exceptions being defined in another class, or for that matter, defined separately out of the main route definition.

I verified this in the logs by looking for the routes being booted ( by routeId ) and also checking when an exception is thrown.

Additionally, to further confirm, I took the http Connect Exception handling route and put that directly in the httpRouteBuilder and lo..! , the exception handling now kicks in just fine for this exception..

Am I missing something here to get all exceptions to work while being nicely defined in its own class. ?

I am using Apache Camel 2.9.0 , but I verified the same behavior also in 2.8.3.

Thanks, Anand


回答1:


correct, the onException() clauses only apply to the current RouteBuilder's route definitions...

that said, you can reuse these definitions by having all your RouteBuilders extend the ExceptionRouteBuilder and call super.configure()...something like this

public class MyRouteBuilder extends ExceptionRouteBuilder {
    @Override
    public void configure() throws Exception {
        super.configure();
        from("direct:start").throwException(new Exception("error"));
    }
}
...
public class ExceptionRouteBuilder implements RouteBuilder {
    @Override
    public void configure() throws Exception {
        onException(Exception.class).handled(true).to("mock:error");
    }
}

or even just have a static method in an ExceptionBuilder class to setup the clauses for a given RouteBuilder instance

public class MyRouteBuilder extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        ExceptionBuilder.setup(this);
        from("direct:start").throwException(new Exception("error"));
    }
}
...
public class ExceptionBuilder {
    public static void setup(RouteBuilder routeBuilder) {
        routeBuilder.onException(Exception.class).handled(true).to("mock:error");
    }  
}



回答2:


Based on the accepted answer, I found a cleaner way to implement exception handling, so you don't have to call super.configure() in every route. Just call a method that handles onException in the constructor of the base class.

//Base class that does exception handling
public abstracExceptionRouteBuildert class BaseAbstractRoute extends RouteBuilder {
  protected BaseAbstractRoute() {
    handleException();
  }

  private void handleException() {
    onException(Exception.class).handled(true).to("mock:error");
  }
}

//Extend the base class
public class MyRouteBuilder extends BaseAbstractRoute {
  @Override
  public void configure() throws Exception {
    from("direct:start").throwException(new Exception("error"));
  }
}


来源:https://stackoverflow.com/questions/9283861/camel-exception-handling-doesnt-work-if-exception-clause-is-defined-in-a-separat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!