Apache Camel 运行 onCompletion 的一部分并且不显示堆栈跟踪

Apache Camel runs part of onCompletion and doesn't show stack trace

我正在尝试使用 Camel 一次轮询路由,如果文件存在则使用它,如果不存在则记录错误。

默认情况下,如果文件不存在,路由将不执行任何操作,因此我首先将 consumer.sendEmptyMessageWhenIdle=true 添加到 URI。然后我检查 null body 来决定是记录异常还是继续:

    from(theFileUri)
        .onCompletion()
            .onCompleteOnly()
            .log("SUCCESS")
            .bean(theOtherAction, "start")
        .end()
        .onException(Exception.class)
            .logStackTrace(true)
            .log(ERROR, "Failed to load file")
            .handled(true)
        .end()
        .choice()
            .when(body().isNotNull())
                .to(NEXT_ROUTE_URI)
            .endChoice()
            .otherwise()
                .throwException(new FileNotFoundException(theFileUri))
            .endChoice();

这有两个问题:

如果有更好的方法,那么我欢迎提出建议,但我也想知道我在这个方法中做错了什么。

我仍然不完全清楚发生了什么。但是,我认为 onException 调用需要从链中分离出来。在我看来 logStackTrace 仅适用于重新投递尝试。尝试次数默认为 0,这就是我想要的。从 Java DSL 访问异常的唯一方法似乎是自定义 ProcessorThe getException() method will return null if you are using handled(true) so you must use Exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class).

我还怀疑来自 onCompletion 的日志消息是由于它 running in parallel 在异常中止之前:

Camel 2.13 or older - On completion runs in separate thread Icon The onCompletion runs in a separate thread in parallel with the original route. It is therefore not intended to influence the outcome of the original route. The idea for on completion is to spin off a new thread to eg send logs to a central log database, send an email, send alterts to a monitoring system, store a copy of the result message etc. Therefore if you want to do some work that influence the original route, then do not use onCompletion for that. Notice: if you use the UnitOfWork API as mentioned in the top of this page, then you can register a Synchronization callback on the Exchange which is executed in the original route. That way allows you to do some custom code when the route is completed; this is how custom components can enlist on completion services which they need, eg the File component does that for work that moves/deletes the original file etc.

因为我不想运行这个代码异常,我想我可以中止异常的路由。

我目前有这个:

    onException(Exception.class)
        .handled(true)
        .process(new Processor()
        {
            @Override
            public void process(Exchange anExchange) throws Exception
            {
                Exception myException = anExchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
                LOGGER.error("Failed to load", myException);
            }
        });
    from(theFileUri)
        .choice()
            .when(body().isNotNull())
                .to(NEXT_ROUTE_URI)
                .log("SUCCESS")
                .bean(theOtherAction, "start")
            .endChoice()
            .otherwise()
                .throwException(new FileNotFoundException(theFileUri));