Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Warning
titleException Clause is tied to the error handler

It's important to notice that the exception clauses are added to the error handler. So if you have not or only have one error handler defined then all exception clauses is configure to the same error handler. Even though you have exception clauses defined in different routes.

So in this situation there will always be 3 exception clauses for both routes

Code Block
java
java
    public void configure() throws Exception {
        // general error handler using [Dead Letter Channel]
        errorHandler(deadLetterChannel("seda:error").maximumRedeliveries(2));

        // excption clauses can also be defined within routes. MUST use .end() to indicate end of exception clause and where the regular routing continues
        from("direct:order")
            .onException(MyOrderException.class).maximumRedeliveries(0).end()
            .to("bean:handleOrder");
        
        from("direct:shipOrder")
            .onException(MyShipException.class).maximumRedeliveries(3).end()
            .onException(Exception.class).handled(true).maximumRedeliveries(0).to("bean:fallbackHandler").end()
            .to("bean:shipOrder");

In the example above we always have 3 exception clauses defined for the same error handler, as we only have one global error handler. So if we are processing an order in the first route, and a MyOrderException is thrown it is caught as expected. However what would be unexpected is that any other exceptions will be triggered to be handled by onException(Exception.class) from the 2nd route.

To fix this you need to add a nested errorHandler as well.

Code Block
java
java
        from("direct:order")
            .errorHandler(deadLetterChannel("seda:orderError").maximumRedeliveries(2));
            .onException(MyOrderException.class).maximumRedeliveries(0).end()
            .to("bean:handleOrder");

Now we have two error handlers with separate exception clauses:

  • global: "seda:error" configured with exception clauses: MyShipException.class and Exception.class
  • route specific: "seda:orderError" configured with exception clause: MyOrderException.class

As this can get complex and confusing, then best practice is therefore to define your onException clauses in the top of your route builder before the actual routes. This way end users see the onException is defined before hand the routing and thus it's intuitive to think them as globally.

Code Block
java
java
    public void configure() throws Exception {
        // general error handler using [Dead Letter Channel]
        errorHandler(deadLetterChannel("seda:error").maximumRedeliveries(2));

        // excption clauses 
        onException(MyOrderException.class).maximumRedeliveries(0);
        onException(MyShipException.class).maximumRedeliveries(3);
        onException(Exception.class).handled(true).maximumRedeliveries(0).to("bean:fallbackHandler");

        // regular routes
        from("direct:order")
            .to("bean:handleOrder");

        from("direct:shipOrder")
            .to("bean:shipOrder");

...