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