英文:
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");
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论