我目前正在所有路由继承的抽象类中完成异常处理。像这样:

    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状态代码在两种情况下返回truefalse。 Camel执行onWhen由Camel执行,以知道要使用哪个onException块(可以有更多的块,但首先使用true)。

  • 您可以在Camel网站或《 Camel in Action》一书中找到更多详细信息,该书整章专门介绍错误处理。

    09-11 18:39