首页 > 解决方案 > 异常处理 Camel Apache

问题描述

我是 Camel Apache 的新手,在异常处理方面遇到了一些麻烦。我要做的是捕获 SalesforceException,然后我需要根据 statusCode 采取不同的操作。

例如,当 statusCode >= 500 我必须尝试重新传递消息。这是一个技术错误。当 statusCode < 500 时,我必须结合请求和响应并将其放在 failureQueue 上。

所以我的问题是:如何尝试在选择定义中重新传递消息?似乎无法在 onException 上使用以下选项:

          .handled(true).useOriginalMessage().maximumRedeliveries(3)
          .redeliveryDelay(5000)
          .logRetryAttempted(true)
          .retryAttemptedLogLevel(LoggingLevel.WARN)

我还尝试抛出我自己定义的新异常,以便我可以从那里处理它,但看起来 FatalFallbackErrorHandler 接管了我没有权力,因为我无法自己处理它。所以我的第二个问题 - 如果在选择定义中重新发送它没有答案 -我如何在没有 ErrorHandler 接管的情况下在自定义异常中处理它?

这是我的代码:

    onException()
         .logStackTrace(true);


    onException(SalesforceException.class)
                .process(new Processor() {
                @Override
                public void process(Exchange exchange) throws Exception {
                    SalesforceException cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, SalesforceException.class);
                    exchange.setProperty("statusCode", cause.getStatusCode());
                    exchange.setProperty("response", cause.getMessage());
                }
            })
            .choice()
                .when(header("statusCode").isGreaterThanOrEqualTo(500))
        // try to redeliverd the orginal message
                    .log(LoggingLevel.WARN, "{{logger}}", "Salesforce exception caught with statusCode >= 500")
                    .throwException(new SalesforceTechnicalException()) 
                .otherwise()
        // combine request & response and put on failurequeue
                    .log(LoggingLevel.WARN, "{{logger}}", "Salesforce exception caught with statusCode < 500, following message will be put on failure queue")                                                  
                    .throwException(new SalesforceFunctionalException())     
            .end();

    onException(SalesforceTechnicalException.class)
    //combine request & response and put on failurequeue
            .transform(ExpressionBuilder.simpleExpression("{\"request\" : ${exchangeProperty.requestBody}, \"response\" : ${exchangeProperty.response}}"))
            .to("log:{{logger}}?level=INFO&showHeaders=true")
            .to("amqp:qFailure?exchangePattern=InOnly");

    onException(SalesforceTechnicalException.class)
    //try resending the orginal message to SF Rest API
            .useOriginalMessage()
            .handled(true)
            .maximumRedeliveries(3)
            .redeliveryDelay(5000)
            .logRetryAttempted(true)

标签: javaexceptionexception-handlingapache-camelsalesforce

解决方案


您应该能够使用一对 onException(SalesforceException.class) 块并使用 onWhen(Predicate) 缩小每个块。

    onException(SalesforceException.class)
        .onWhen(new Predicate() {

            @Override
            public boolean matches(Exchange exchange) {
                SalesforceException cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, SalesforceException.class);
                return cause.getStatusCode() < 500;
            }
        })
        .log("Handled here if statusCode < 500")
        .useOriginalMessage()
        .handled(true)
        .maximumRedeliveries(3)
        .redeliveryDelay(5000)
        .logRetryAttempted(true);

    onException(SalesforceException.class)
        .onWhen(new Predicate() {

            @Override
            public boolean matches(Exchange exchange) {
                SalesforceException cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, SalesforceException.class);
                return cause.getStatusCode() >= 500;
            }
        })
        .log("Handled here if statusCode >= 500")
        .transform(ExpressionBuilder.simpleExpression("{\"request\" : ${exchangeProperty.requestBody}, \"response\" : ${exchangeProperty.response}}"))
        .to("log:{{logger}}?level=INFO&showHeaders=true")
        .to("amqp:qFailure?exchangePattern=InOnly");

推荐阅读