Error handling 从onRedelivery触发新的OneException路由

Error handling 从onRedelivery触发新的OneException路由,error-handling,apache-camel,Error Handling,Apache Camel,我有一个ErrorHandler(DefaultErrorHandler),我在其中提供了一个onRedeliveryref。默认情况下,ErrorHandler无限次重试。但是,如果存在某个条件(当前由onRedeliveryref确定),我希望退出redelivery循环并执行不同的路由 我最初的想法是使用onRedeliveryref抛出和异常,并使用适当的onException将其引导到适当的路径。但是,我发现,RedeliveryErrorHandler捕获了这个异常并保持循环 我还发

我有一个
ErrorHandler
DefaultErrorHandler
),我在其中提供了一个
onRedelivery
ref。默认情况下,
ErrorHandler
无限次重试。但是,如果存在某个条件(当前由
onRedelivery
ref确定),我希望退出redelivery循环并执行不同的路由

我最初的想法是使用
onRedelivery
ref抛出和异常,并使用适当的
onException
将其引导到适当的路径。但是,我发现,
RedeliveryErrorHandler
捕获了这个异常并保持循环

我还发现我可以将
Exchange.REDELIVERY\u
设置为true,这将退出REDELIVERY循环,但不会将我指向恢复路径

有什么建议吗

编辑

因此,我发现,如果我将原始异常类型添加到
RouteBuilder
中异常类型的
OneException
,其中有我的
ErrorHandler
,并且如果我将
Exchange.REDELIVERY
设置为true,原始异常将被抛出到
RouteBuilder
范围,并被
OneException
捕获。然而,我更愿意抛出并捕获一个新的异常类型,这样处理对于这种情况是显式的

回答


因此,
Peter的
建议使用
retryWhile
非常好,因为它允许我通过编程确定何时停止重试。太贵了。这只是想法的一半。第二部分是将失败的交换发送到新的/不同的路由以进行错误处理。这是通过使用
死信频道
而不是
默认错误处理程序

来实现的,将
retryWhile
死信频道
结合使用:

public class MyRouteBuilder extends RouteBuilder {
    @Override
    public void configure() {
        errorHandler(deadLetterChannel("direct:special")
            .retryWhile(method(new MyPredicate())));

        from("direct:start")
            .log("Starting...")
            .throwException(new Exception("dummy"));

        from("direct:special")
            .log("...Special");
    }
}

public class MyPredicate implements Predicate {
    @Override
    public boolean matches(final Exchange exchange) {
        AtomicInteger counter = exchange.getProperty("myCounter");
        if (counter == null) {
            counter = new AtomicInteger(0);
            exchange.setProperty("myCounter", counter);
        }
        int count = counter.incrementAndGet();
        LOG.info("Count = {}", count);
        return count < 3; // or whatever condition is suitable
    }
}

嗨,Peter,您不应该将状态信息(count)存储到MyPredicate实例中。当需要处理多个异常时,保持谓词实例无状态可以避免某些有线错误。@WillemJiang感谢您的提示。我相应地更新了我的示例。+1这看起来完全正确。我要先测试一下它是否有效,然后再把它标记为正确答案。谢谢@彼得,现在好多了:)
INFO  Starting...
INFO  Count = 1
INFO  Count = 2
INFO  Count = 3
INFO  ...Special