Grails中的Camel异常处理
我目前在所有路由继承的抽象类中进行异常处理。大概是这样的:Grails中的Camel异常处理,grails,exception-handling,apache-camel,Grails,Exception Handling,Apache Camel,我目前在所有路由继承的抽象类中进行异常处理。大概是这样的: onException(SocketException,HttpOperationFailedException) .handled(true) .maximumRedeliveries(settings.maximumRedeliveries) .redeliverDelay(settings.redeliverDelay) .useCollisionAvoida
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 get。对于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()
OneException(HttpOperationFailedException)
.已处理(正确)
.进程{Exchange x->
HttpOperationFailedException ex=x.getProperty(Exchange.EXCEPTION\u已捕获,HttpOperationFailedException.class)
log.debug(“捕获到HttpOperationFailedException:statusCode=${ex?.statusCode}”)
ProducerTemplate producer=x.getContext().createProducerTemplate()
如果(ex?.statusCode>=400&&ex?.statusCode<500){
调试(“跳过重试…”)
producer.send(routeFailedEndpoint,x)
x、 in.body=“请求:\n${x.in.body}\n\n响应:${ex.statusCode}\n${ex.responseBody}.toString()
如果(sendFailedEmailEnabled)
producer.send('direct:routeFailedEmailHandler',x)
}否则{
producer.send(routeFailedRetryEndpoint,x)
}
}.停止
如何像在第一个代码段中那样添加重试代码?我尝试使用嵌套的choice()…when()…otherwise()子句,但不断出现编译错误
有人必须做类似的事情吗
下面是我的代码,其中包含嵌套的choice()…when()…otherwise()子句:
OneException(HttpOperationFailedException)
.已处理(正确)
.choice()
。当{Exchange x->
HttpOperationFailedException ex=x.getProperty(Exchange.EXCEPTION\u已捕获,HttpOperationFailedException.class)
log.debug(“捕获到HttpOperationFailedException:statusCode=${ex?.statusCode}”)
如果(ex?.statusCode>=400&&ex?.statusCode<500){
调试(“跳过重试…”)
x、 in.body=“请求:\n${x.in.body}\n\n响应:${ex.statusCode}\n${ex.responseBody}.toString()
返回true//不重试
}
调试(“执行重试…”)
返回false//do尝试重试
}.choice()
.when{!sendFailedEmailEnabled}.to(routeFailedEndpoint)
.否则()
.multicast().to(routeFailedEndpoint,'direct:routeFailedEmailHandler')。endChoice()
.否则()
.getParent().getParent().getParent()
.maximumRedeliveries(设置.maximumRedeliveries)
.RedeliveDelay(设置.RedeliveDelay)
.UseCollisionAvoidation()的用法
.collisionAvoidanceFactor(设置.collisionAvoidanceFactor)
.OnRetelivery(重新交付处理器)
.to(路由文件协调器)
您必须有2个OneException块:
- 一个
,具有用于重新交付尝试的重新交付设置onException
- 另一个
,处理异常并发送电子邮件和您想要做的事情onException
- 在两个
块上使用onException
,根据http状态代码在两种情况下返回onWhen
或true
。onWhen由Camel执行,以知道要使用哪一个onException块(可以有更多块,但首先要返回true)false
您可以在Camel网站或Camel in Action手册中找到更多详细信息,该手册有一整章专门介绍错误处理。谢谢,克劳斯,您为我指明了正确的方向 基本上,正如克劳斯所说,使用多个OneException块,每个块使用一个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)
OneException(HttpOperationFailedException)
.onWhen(新谓词(){
公共布尔匹配(Exchange){
HttpOperationFailedException ex=exchange.getProperty(exchange.EXCEPTION\u已捕获,HttpOperationFailedException.class)
log.debug(“捕获到HttpOperationFailedException:statusCode=${ex?.statusCode},正在处理4XX错误”)
返回(ex?.statusCode>=400&&ex?.statusCode<500)
}
}).已处理(正确)
.to(路由指定点)
.choice()
.when{sendFailedEmailEnabled}.process(prepareFailureEmail).to('direct:routeFailedEmailHandler'))
OneException(HttpOperationFailedException)
.onWhen(新谓词(){
公共布尔匹配(Exchange){
HttpOperationFailedException ex=exchange.getProperty(exchange.EXCEPTION\u已捕获,HttpOperationFailedException.class)
log.debug(“捕获到HttpOperationFailedException:statusCode=${ex?.statusCode},处理>=500错误”)
返回(ex?.statusCode>=500)
}
}).已处理(正确)
.maximumRedeliveries(设置.maximumRedeliveries)
.RedeliveDelay(设置.RedeliveDelay)
.UseCollisionAvoidation()的用法
.collisionAvoidanceFactor(设置.collisionAvoidanceFactor)
.OnRetelivery(重新交付处理器)
.to(路由文件协调器)
谢谢你,克劳斯。我要试一试。
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)