Reputation: 747
It seems i don't understand some underlying concepts about custom Exceptions handling in Spring Integration(
I need to intercept some of my RuntimeException-derived custom exceptions (thrown from some my Java method) and depending of it's type route the app execution flow to some other route.
I use the Spring Integration version 4.3.10.RELEASE.
To do this i declare the int:exception-type-router like this:
<int:exception-type-router input-channel="errorChannel" default-output-channel="nullChannel">
<int:mapping exception-type="com.surr.exception.SurrRoutingException"
channel="handleRedirectChannel"/>
<int:mapping exception-type="com.surr.exception.SurrFatalException"
channel="surrChannelMain"/>
<!-- some more mappings -->
</int:exception-type-router>
Channel declaration sample:
<int:channel id="handleRedirectChannel"
datatype="com.surr.exception.SurrRoutingException">
<int:queue/>
</int:channel>
After my Exception throwing i cannot step into related channels. What i'm doing wrong? Maybe i've missed smth in the app initial setup?
Thanks a lot for any assist.
Update After notes from Artem i made some changes described below:
<int:channel id="errorChannel1">
<int:queue capacity="500"/>
</int:channel>
<int:header-enricher>
<int:header name="errorChannel" value="errorChannel1"/>
</int:header-enricher>
<int:exception-type-router input-channel="errorChannel1" default-output-channel="nullChannel">
<int:mapping exception-type="java.lang.Throwable"
channel="handleRedirectChannel"/>
<int:mapping exception-type="java.lang.RuntimeException"
channel="handleRedirectChannel"/>
<int:mapping exception-type="com.surr.exception.SurrRoutingException"
channel="handleRedirectChannel"/>
<int:mapping exception-type="com.surr.exception.SurrFatalException"
channel="surrChannelMain"/>
</int:exception-type-router>
<int:channel id="handleRedirectChannel">
<int:queue capacity="50"/>
</int:channel>
<int:channel id="surrChannelMain">
<int:queue capacity="50"/>
</int:channel>
So far there is no any tracks of my thrown Exceptions. I suspect there are some more rules exist to catch the Exception but can't figure them out
One more update I've issued my exception manually using MessageBuilder (MessageBuilder.withPayload(new MyExceptionObjectWithNeededArguments).build()) and sent it to the 'errorChannel1'. Still no effect(
Stack trace
2021-02-17 23:03:48,742 INFO [ task-scheduler-20 ] [] !! IntentsService.prepareMessages
com.azoft.fakturachat.surrogate.exception.SurrogateRoutingException: Got empty intent description by scenario: [default] and tip: [some_unknown_intent]
at com.azoft.fakturachat.surrogate.IntentsService.fetchIntentDescription(IntentsService.java:84) ~[main/:?]
at com.azoft.fakturachat.surrogate.IntentsService.lambda$prepareMessages$0(IntentsService.java:58) ~[main/:?]
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[?:1.8.0_172]
at java.util.Collections$2.tryAdvance(Collections.java:4717) ~[?:1.8.0_172]
at java.util.Collections$2.forEachRemaining(Collections.java:4725) ~[?:1.8.0_172]
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[?:1.8.0_172]
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[?:1.8.0_172]
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[?:1.8.0_172]
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:1.8.0_172]
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[?:1.8.0_172]
at com.azoft.fakturachat.surrogate.IntentsService.prepareMessages(IntentsService.java:59) ~[main/:?]
at com.azoft.fakturachat.surrogate.IntentsService$$FastClassBySpringCGLIB$$d29d5141.invoke(<generated>) ~[main/:?]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at com.azoft.fakturachat.aspect.LoggingAspect.logMethod(LoggingAspect.java:31) [main/:?]
at sun.reflect.GeneratedMethodAccessor131.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_172]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_172]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at com.azoft.fakturachat.surrogate.IntentsService$$EnhancerBySpringCGLIB$$9cfa94da.prepareMessages(<generated>) [main/:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_172]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_172]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_172]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_172]
at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:113) [spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:129) [spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49) [spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:347) [spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88) [spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131) [spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:330) [spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:169) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:128) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.ExpressionEvaluatingMessageProcessor.processMessage(ExpressionEvaluatingMessageProcessor.java:72) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.transformer.support.ExpressionEvaluatingHeaderValueMessageProcessor.processMessage(ExpressionEvaluatingHeaderValueMessageProcessor.java:71) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.transformer.HeaderEnricher.transform(HeaderEnricher.java:119) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:89) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.MessageHandlerChain.handleMessageInternal(MessageHandlerChain.java:110) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:194) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.MessageHandlerChain$1.send(MessageHandlerChain.java:129) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:292) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:212) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:129) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.MessageHandlerChain$1.send(MessageHandlerChain.java:129) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:292) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:212) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:129) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.MessageHandlerChain$1.send(MessageHandlerChain.java:129) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:292) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:212) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:129) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.DelayHandler.doReleaseMessage(DelayHandler.java:376) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.DelayHandler.access$500(DelayHandler.java:83) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.DelayHandler$ReleaseMessageHandler.handleMessage(DelayHandler.java:470) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.DelayHandler.releaseMessage(DelayHandler.java:368) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.DelayHandler.access$100(DelayHandler.java:83) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.integration.handler.DelayHandler$1.run(DelayHandler.java:328) [spring-integration-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) [spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_172]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_172]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_172]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [?:1.8.0_172]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_172]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_172]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_172]
2021-02-17 23:03:48,751 INFO [ task-scheduler-20 ] [] <- IntentsService.prepareMessages, procTime=306
The 'errorChannel1' channel was introduced only to test this issue. There is no other consumer(s) except this 'exception-type-router'
Exception is 'thrown' in the following way:
SurrRoutingException ex1 = new SurrRoutingException(
MessageFormat.format("Failed to find intent description by scenario: [{0}] and tip: [{1}]",
scenario, tip), context);
errorChannel.send(MessageBuilder.withPayload(ex1).build());
Error channel declaration:
private final QueueChannel errorChannel;
@Autowired
public IntentsService(@Qualifier("errorChannel1") QueueChannel errorChannel)
{
this.errorChannel = errorChannel;
}
Upvotes: 0
Views: 1107
Reputation: 747
I've returned to this issue again. Didn't make a sample project yet but found some info in docs. "SI error handling": "The most important thing to understand here is that the messaging-based error handling applies only to exceptions that are thrown by a Spring Integration task that is executing within a TaskExecutor. This does not apply to exceptions thrown by a handler that operates within the same thread as the sender (for example, through a DirectChannel as described earlier in this section)".
Maybe here is the problem? My app logic is splitted between different chains and routes and maybe some of them are executed not within TaskExecutor and because of it the global interception is not working? i assume that a single, global-scope interceptor per the whole application is not enough. I'm going to verify this assumption. Thanks!
Upvotes: 0
Reputation: 121560
I think your confuse is because an <int:exception-type-router>
can deal with stack trace to track an expected exception down, but datatype
on the channel is exact type of the payload.
See docs for more info:
I would say you don't need a datatype
for that handleRedirectChannel
since you use it only from that router. The point of datatype
is really to restrict producers for this channel which make sense when our application is complex enough and may work even in distributed state when we can't control producers. It doesn't look like a case for your exception router...
Upvotes: 1