我目前在我的所有路由都继承的抽象类中完成了异常处理。像这样:
onException(SocketException,HttpOperationFailedException)
.handled(true)
.maximumRedeliveries(settings.maximumRedeliveries)
.redeliverDelay(settings.redeliverDelay)
.useCollisionAvoidance()
.collisionAvoidanceFactor(settings.collisionAvoidanceFactor)
.onRedelivery(redeliveryProcessor)
.log('retry failed, sending to the route failed coordinator')
.to(routeFailedCoordinator)
现在,我想根据不同的响应代码做一些不同的事情。对于200以外的所有代码,抛出HttpOperationFailedException。对于4XX代码,我想将消息发送到失败的队列并发送电子邮件(如果为该特定路由启用)。对于所有其他错误,我想要经历重试周期。以下是适用于4XX错误的内容:
onException(HttpOperationFailedException)
.handled(true)
.process { Exchange x ->
HttpOperationFailedException ex = x.getProperty(Exchange.EXCEPTION_CAUGHT, HttpOperationFailedException.class)
log.debug("Caught a HttpOperationFailedException: statusCode=${ex?.statusCode}")
ProducerTemplate producer = x.getContext().createProducerTemplate()
if (ex?.statusCode >= 400 && ex?.statusCode < 500) {
log.debug("Skipping retries ...")
producer.send(routeFailedEndpoint, x)
x.in.body = "Request:\n${x.in.body}\n\nResponse: ${ex.statusCode}\n${ex.responseBody}".toString()
if (sendFailedEmailEnabled)
producer.send('direct:routeFailedEmailHandler', x)
} else {
producer.send(routeFailedRetryEndpoint, x)
}
}.stop()
如何在第一个代码段中添加重试代码?我尝试使用嵌套的choice()... when()... otherwise()子句并不断收到编译错误。
任何人都必须做类似的事情吗?
这是我的代码,嵌套的选择().. when().. otherwise()子句:
onException(HttpOperationFailedException)
.handled(true)
.choice()
.when { Exchange x ->
HttpOperationFailedException ex = x.getProperty(Exchange.EXCEPTION_CAUGHT, HttpOperationFailedException.class)
log.debug("Caught a HttpOperationFailedException: statusCode=${ex?.statusCode}")
if (ex?.statusCode >= 400 && ex?.statusCode < 500) {
log.debug("Skipping retries ...")
x.in.body = "Request:\n${x.in.body}\n\nResponse: ${ex.statusCode}\n${ex.responseBody}".toString()
return true // don't retry
}
log.debug("Performing retries ...")
return false // do attempt retries
}.choice()
.when { !sendFailedEmailEnabled }.to(routeFailedEndpoint)
.otherwise()
.multicast().to(routeFailedEndpoint, 'direct:routeFailedEmailHandler').endChoice()
.otherwise()
.getParent().getParent().getParent()
.maximumRedeliveries(settings.maximumRedeliveries)
.redeliverDelay(settings.redeliverDelay)
.useCollisionAvoidance()
.collisionAvoidanceFactor(settings.collisionAvoidanceFactor)
.onRedelivery(redeliveryProcessor)
.to(routeFailedCoordinator)
答案 0 :(得分:0)
你必须有2个onException块:
onException
,其中包含重新传递尝试的重新传递设置onException
以及您想要做的事情。onWhen
块上使用onException
,根据该http状态代码在任一情况下返回true
或false
。 onWhen由Camel执行以了解要使用哪个onException块(您可以使用更多,但首先使用返回true)。您可以在Camel网站或Camel in Action一书中找到更多详细信息,其中有一章专门介绍错误处理。
答案 1 :(得分:0)
谢谢,克劳斯,你指出了我正确的方向。
基本上,正如克劳斯所说,使用多个onException块,每个块都使用onWhen子句......
onException(HttpOperationFailedException)
.onWhen(new Predicate() {
public boolean matches(Exchange exchange) {
HttpOperationFailedException ex = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, HttpOperationFailedException.class)
log.debug("Caught an HttpOperationFailedException: statusCode=${ex?.statusCode}, processing 4XX error")
return (ex?.statusCode >= 400 && ex?.statusCode < 500)
}
}).handled(true)
.to(routeFailedEndpoint)
.choice()
.when { sendFailedEmailEnabled }.process(prepareFailureEmail).to('direct:routeFailedEmailHandler')
onException(HttpOperationFailedException)
.onWhen(new Predicate() {
public boolean matches(Exchange exchange) {
HttpOperationFailedException ex = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, HttpOperationFailedException.class)
log.debug("Caught an HttpOperationFailedException: statusCode=${ex?.statusCode}, processing >=500 error")
return (ex?.statusCode >= 500)
}
}).handled(true)
.maximumRedeliveries(settings.maximumRedeliveries)
.redeliverDelay(settings.redeliverDelay)
.useCollisionAvoidance()
.collisionAvoidanceFactor(settings.collisionAvoidanceFactor)
.onRedelivery(redeliveryProcessor)
.to(routeFailedCoordinator)