我目前正在所有路由继承的抽象类中完成异常处理。像这样:
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()子句,并不断出现编译错误。
任何人都必须做类似的事情吗?
这是我的带有嵌套choice().. 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)
最佳答案
您将必须具有2个onException块:
onException
,用于重新交付尝试onException
。 onWhen
块上都使用onException
,以根据该http状态代码在两种情况下返回true
或false
。 Camel执行onWhen由Camel执行,以知道要使用哪个onException块(可以有更多的块,但首先使用true)。 您可以在Camel网站或《 Camel in Action》一书中找到更多详细信息,该书整章专门介绍错误处理。