不当的异常处理,当 Apache Camel 拦截器抛出异常时。

huangapple go评论65阅读模式
英文:

Inappropriate exception when apache camel interceptor throws one

问题

我创建了一个拦截器来测试Camel路由中的异常处理程序。以下是拦截器的代码部分:

context.getRouteDefinition("AnalisingResponse").adviceWith(context,
    new AdviceWithRouteBuilder() {
        @Override
        public void configure() {
            interceptSendToEndpoint("direct:PsMessageLogger_updateMessage")
                .routeId("interceptor")
                .skipSendToOriginalEndpoint()
                .throwException(exception);
        }
    });

我希望应用AdviceWith的路由如下:

from("direct:AnalisingResponse")
    .routeId("AnalisingResponse")
    .log("start PsASetStatementProcessor_AnalisingResponse")
    .process(exchange -> {
        exchange.setProperty(CONDITION,
            bodyDataContainer(exchange)
                .getValue("/*[1]/Body/container/Msg/BSMessage/BSError/@Cod")  // TODO local-name
        );
    })
    // 后续处理步骤...

以下是我希望拦截的另一个路由:

from("direct:PsMessageLogger_updateMessage")
    .routeId("PsMessageLogger_updateMessage")
    .log("start PsMessageLogger_updateMessage")
    .onException(Exception.class)
        .handled(true)
        .to("direct:PsMessageLogger_updateMessage_errorHandler")
    .end()
    // 后续处理步骤...

但是结果是,EXCEPTION_CAUGHT属性中包含的不是我抛出的异常,而是org.apache.camel.CamelExecutionException,其中原因是NullPointerException。以下是其堆栈跟踪:

org.apache.camel.CamelExecutionException: 在交换过程中发生异常: Exchange[ID-SERVO-1598117736905-0-3]
    // 更多堆栈信息...
Caused by: java.lang.NullPointerException
	at java.util.ArrayDeque.addFirst(ArrayDeque.java:233)
    // 更多堆栈信息...

有关如何在错误处理程序中获取所需的异常,我该如何做呢?

英文:

I created an interceptor to test the exception handler in Camel route.
Here's an interceptor:

context.getRouteDefinition("AnalisingResponse").adviceWith(context,
            new AdviceWithRouteBuilder() {
                @Override
                public void configure() {
                    interceptSendToEndpoint("direct:PsMessageLogger_updateMessage")
                        .routeId("interceptor")
                        .skipSendToOriginalEndpoint()
                        .throwException(exception);
                }
            });

route i wish to apply adviceWith:

      from("direct:AnalisingResponse")
            .routeId("AnalisingResponse")
            .log("start PsASetStatementProcessor_AnalisingResponse")
            .process(exchange -> {
                exchange.setProperty(CONDITION,
                    bodyDataContainer(exchange)
                        .getValue("/*[1]/Body/container/Msg/BSMessage/BSError/@Cod")  // TODO local-name
                );
            })
            .process((BaseAction) exchange -> {
                DataContainer localBody = propertyDataContainer(exchange, LOCAL_BODY);

                Long serviceId = Long.parseLong(localBody.getValue("/Message/ServiceID"));
                Long taskId = Long.parseLong(localBody.getValue("/Message/TaskID"));
                Long statusId = 39L;
                Long mtType = 0L;

                String requestVar = bsDbSwiftCorpService.updateTask(taskId, serviceId, mtType, statusId);

                exchange.setProperty(REQUEST_VAR, requestVar);
            })
            .process((BaseAction) exchange -> {
                DataContainer localBody = propertyDataContainer(exchange, LOCAL_BODY);
                localBody.replace("./Message/MessageStatusID", "3");
                exchange.setProperty(LOCAL_BODY, localBody);

                template.sendBody(PsMessageLogger.DIRECT_ROUTE_UPDATE_MESSAGE, localBody.copy());
            });

and here's a route, i wish to intercept:

        from("direct:PsMessageLogger_updateMessage")
                .routeId("PsMessageLogger_updateMessage")
                .log("start PsMessageLogger_updateMessage")
                .onException(Exception.class)
                    .handled(true)
                    .to("direct:PsMessageLogger_updateMessage_errorHandler")
                .end()
                .process((BaseAction) exchange -> {
                    DataContainer body = bodyDataContainer(exchange);

                    Long messageID = new Long(body.getValue("/Message/MessageID"));
                    Long messageStatusID = new Long(body.getValue("/Message/MessageStatusID"));
                    Long taskID = new Long(body.getValue("/Message/TaskID"));
                    Long taskStatusGenID = new Long(body.getValue("/Message/TaskStatusGenID"));

                    bsMessageLoggerToDbService.updateMessage(messageID, messageStatusID, taskID, taskStatusGenID);
                });

But as a result, the EXCEPTION_CAUGHT property contains not the exception thrown by me, but org.apache.camel.CamelExecutionException where cause is a NullPointerException. Here's its stacktrace:

org.apache.camel.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[ID-SERVO-1598117736905-0-3]
	at org.apache.camel.util.ObjectHelper.wrapCamelExecutionException(ObjectHelper.java:1842)
	at org.apache.camel.util.ExchangeHelper.extractResultBody(ExchangeHelper.java:715)
	at org.apache.camel.impl.DefaultProducerTemplate.extractResultBody(DefaultProducerTemplate.java:515)
	at org.apache.camel.impl.DefaultProducerTemplate.extractResultBody(DefaultProducerTemplate.java:511)
	at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:163)
	at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:168)
	at ru.vtb.swiftcorp.psASetStatementProcessor.proxy.services.PsASetStatementProcessor.lambda$configure$8(PsASetStatementProcessor.java:149)
	at ru.vtb.swiftcorp.common.BaseAction.process(BaseAction.java:30)
	at org.apache.camel.processor.DelegateSyncProcessor.process(DelegateSyncProcessor.java:63)
	at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
	at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
	at org.apache.camel.processor.Pipeline.process(Pipeline.java:138)
	at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
	at org.apache.camel.processor.ChoiceProcessor.process(ChoiceProcessor.java:117)
	at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
	at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
	at org.apache.camel.processor.Pipeline.process(Pipeline.java:138)
	at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
	at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
	at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:76)
	at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:148)
	at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
	at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
	at org.apache.camel.processor.Pipeline.process(Pipeline.java:138)
	at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
	at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
	at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:76)
	at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:148)
	at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)
	at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
	at org.apache.camel.processor.Pipeline.process(Pipeline.java:138)
	at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
	at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
	at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:76)
	at org.apache.camel.processor.SharedCamelInternalProcessor.process(SharedCamelInternalProcessor.java:186)
	at org.apache.camel.processor.SharedCamelInternalProcessor.process(SharedCamelInternalProcessor.java:86)
	at org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:529)
	at org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:494)
	at org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:369)
	at org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.java:494)
	at org.apache.camel.impl.ProducerCache.send(ProducerCache.java:229)
	at org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:144)
	at org.apache.camel.builder.DefaultFluentProducerTemplate.send(DefaultFluentProducerTemplate.java:306)
	at ru.vtb.swiftcorp.psASetStatementProcessor.proxy.services.PsASetStatementProcessorTest.testSuccessRoute_caseExceptionOnPsMessageLogger_updateMessage(PsASetStatementProcessorTest.java:546)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
	at org.junit.rules.RunRules.evaluate(RunRules.java:20)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: java.lang.NullPointerException
	at java.util.ArrayDeque.addFirst(ArrayDeque.java:233)
	at java.util.ArrayDeque.push(ArrayDeque.java:508)
	at org.apache.camel.processor.FatalFallbackErrorHandler.process(FatalFallbackErrorHandler.java:79)
	at org.apache.camel.processor.RedeliveryErrorHandler.deliverToFailureProcessor(RedeliveryErrorHandler.java:1063)
	at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:474)
	at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)
	at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:97)
	at org.apache.camel.impl.InterceptSendToEndpointProcessor.process(InterceptSendToEndpointProcessor.java:80)
	at org.apache.camel.processor.SharedCamelInternalProcessor.process(SharedCamelInternalProcessor.java:186)
	at org.apache.camel.processor.SharedCamelInternalProcessor.process(SharedCamelInternalProcessor.java:86)
	at org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:529)
	at org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:494)
	at org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:369)
	at org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.java:494)
	at org.apache.camel.impl.ProducerCache.send(ProducerCache.java:229)
	at org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:144)
	at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:161)
	... 66 more

Everything that was possible to understand that the error occurs in the method public boolean process(final Exchange exchange, final AsyncCallback callback) of org.apache.camel.processor.FatalFallbackErrorHandler when trying to put null value in the deque.

How do i get the exception i need in the error handler?

答案1

得分: 0

interceptSendToEndpoint("direct:PsMessageLogger_updateMessage") 在尝试拦截时会查找实际字符串 direct:PsMessageLogger_updateMessage。在你的 AnalisingResponse 路由中,你在处理器中动态执行这个操作,这就是为什么它无法拦截。

在你的 AnalisingResponse 的第三个处理器中,移除生产者模板并将 localBody 设置为你的消息体,就像这样:exchange.getIn().setBody(localBody)。然后在处理方法之后,添加一个 to("direct:PsMessageLogger_updateMessage")

你的 AnalisingResponse 路由应该是这样的:

from("direct:AnalisingResponse")
	.routeId("AnalisingResponse")
	.log("start PsASetStatementProcessor_AnalisingResponse")
	.process(exchange -> {
		//...
	})
	.process((BaseAction) exchange -> {
		//...
	})
	.process((BaseAction) exchange -> {
		DataContainer localBody = propertyDataContainer(exchange, LOCAL_BODY);
		localBody.replace("./Message/MessageStatusID", "3");
		exchange.setProperty(LOCAL_BODY, localBody);
		
		exchange.getIn().setBody(localBody);
	})
	.to("direct:PsMessageLogger_updateMessage");
英文:

interceptSendToEndpoint("direct:PsMessageLogger_updateMessage") looks for the actual string direct:PsMessageLogger_updateMessage when attempting to intercept. In your AnalisingResponse route, you are doing it dynamically in your processor which is why it is unable to intercept.

In the 3rd processor in your AnalisingResponse, remove the Producer Template and set the localBody as your message body like so: exchange.getIn().setBody(localBody). Then after the process method, add a to("direct:PsMessageLogger_updateMessage").

Your AnalisingResponse route should look like this:

from("direct:AnalisingResponse")
	.routeId("AnalisingResponse")
	.log("start PsASetStatementProcessor_AnalisingResponse")
	.process(exchange -> {
		//...
	})
	.process((BaseAction) exchange -> {
		//...
	})
	.process((BaseAction) exchange -> {
		DataContainer localBody = propertyDataContainer(exchange, LOCAL_BODY);
		localBody.replace("./Message/MessageStatusID", "3");
		exchange.setProperty(LOCAL_BODY, localBody);
		
		exchange.getIn().setBody(localBody);
	})
	.to("direct:PsMessageLogger_updateMessage");

huangapple
  • 本文由 发表于 2020年8月23日 01:47:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63539298.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定