Apache Camel onException自定义错误处理程序不工作

efzxgjgh  于 2022-11-07  发布在  Apache
关注(0)|答案(2)|浏览(304)

我对apache camel特性不熟悉。所以我在我们的项目中遇到了DefaultErrorHandler的问题。
有一些错误我们没有使用任何自定义错误处理程序。每当异常发生时,apache camel都会记录它,这个日志级别是ERROR。由于没有任何自定义错误处理程序,Apache camel通过DefaultErrorHandler将异常传播回调用者来处理故障。
此错误类似于“找不到用户”,因此这不应该是错误,这可能是警告信息。由于我们不处理此错误,因此由Apache Camel的DefaultErrorHandler处理。
服务器上的错误日志如下:

main 2022-08-05 15:24:43.537 ERROR [user-manager] 1 --- [nio-8080-exec-5] o.a.c.p.e.DefaultErrorHandler            : Failed delivery for (MessageId:-0000000 on Exc │    │
│ main +[                                                                                                                                                                                                                                      │    │
│ main +[ Message History (complete message history is disabled)                                                                                                                                                                               │    │
│ main +[ ---------------------------------------------------------------------------------------------------------------------------------------                                                                                              │    │
│ main +[ RouteId              ProcessorId          Processor                                                                        Elapsed (ms)                                                                                              │    │
│ main +[ [PostUserToIdentity] [PostUserToIdentity] [from[direct://business.postUserToIdentity]                                    ] [        27]                                                                                              │    │
│ main +[     ...                                                                                                                                                                                                                              │    │
│ main +[ [PostUserToIdentity] [to58              ] [direct:postUserToIdentityRequestedInternal                                    ] [         0]                                                                                              │    │
│ main +[                                                                                                                                                                                                                                      │    │
│ main +[ Stacktrace                                                                                                                                                                                                                           │    │
│ main +[ ---------------------------------------------------------------------------------------------------------------------------------------                                                                                              │    │
│ main +[                                                                                                                                                                                                                                      │    │
│ main                                                                                                                                                                                                                                         │    │
│ main com.user.manager.exception.ConflictException: User already exists

因此,我编写了一个自定义处理程序和一个RouteClass,它使用适当的CamelOnException子句扩展了RouteBuilder

发生冲突时异常路由类

@Component
public class OnConflictExceptionRoute extends RouteBuilder {

    @Override
    public void configure() {
        log.info("Configuring extended create user by context route");

        onException(ConflictException.class)
            .process(new ConflictExceptionHandler())
            .handled(true);

        from("direct:business.postUserToIdentity")
            .routeId("PostUserToIdentity")
            .onException(ConflictException.class)
            .process(new ConflictExceptionHandler());
    }
}

自定义错误处理程序

@Slf4j
public class ConflictExceptionHandler implements Processor {

    @Override
    public void process(Exchange exchange) {
        log.info("USER ALREADY EXISTS!");
        throw new ConflictException().withMessage("USER ALREADY EXISTS!");
    }
}

在应用程序启动时,我可以看到RouteClass中的Configure方法被触发。
但是,当我触发流时,我仍然看到DefaultErrorHandler正在处理相同的错误。
为什么不工作?是否缺少任何配置?谢谢。

sycxhyv7

sycxhyv71#

Camel具有不同的异常处理行为。基于路由:在你例子中,postUserToIdentity路由有一个基于路由的异常处理程序,它覆盖了其他的异常处理程序。另一个基于RouteBuilder的异常处理程序。它处理routebuilder类中的所有路由。你有两个定义。它们有相同的onException。这是不符合逻辑的。你可以像这样修改你的代码。

onException(ConflictException.class)
                .process(new ConflictExceptionHandler())
                .handled(true)
                .log("Exception handler works ${exception}");

        from("direct:business.postUserToIdentity")
                .routeId("PostUserToIdentity")
                .log("started")
                .throwException(new ConflictException());
uqcuzwp8

uqcuzwp82#

因此,经过深入分析后,我发现我可以通过扩展RouteBuilder类来解决我们在应用程序中调用的服务的问题,如下所示。

@Override
    protected ErrorHandlerFactory createErrorHandlerBuilder() {
        DefaultErrorHandlerBuilder errorHandlerBuilder = super.defaultErrorHandler();
        // Changed from ERROR because it is expected that the service handles the exception.
        errorHandlerBuilder.setLevel(LoggingLevel.INFO.toString());
        RedeliveryPolicyDefinition policy = new RedeliveryPolicyDefinition();
        policy.setDisableRedelivery("false");
        policy.setRetriesExhaustedLogLevel(getRetriesExhaustedLogLevel().toString());
        errorHandlerBuilder.setRedeliveryPolicy(policy);
        return errorHandlerBuilder;
    }

注意:ExhaustedLogLevel设置为调试

相关问题