Весенняя интеграция. Как отловить кастомное исключение?

Кажется, я не понимаю некоторых основных концепций обработки пользовательских исключений в Spring Integration (

Мне нужно перехватить некоторые из моих пользовательских исключений, производных от RuntimeException (выброшенных из какого-то моего метода Java), и в зависимости от его типа перенаправить поток выполнения приложения на другой маршрут.

Я использую Spring Integration версии 4.3.10.RELEASE.

Для этого я объявляю int: exception-type-router следующим образом:

<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>

Образец объявления канала:

<int:channel id="handleRedirectChannel"
     datatype="com.surr.exception.SurrRoutingException">
      <int:queue/>
</int:channel>

После выброса исключения я не могу перейти на связанные каналы. Что я делаю не так? Может, я что-то пропустил в начальной настройке приложения?

Большое спасибо за любую помощь.

Обновление. После заметок Артема я внес некоторые изменения, описанные ниже:

  1. Введен дополнительный канал ошибки:
<int:channel id="errorChannel1">
        <int:queue capacity="500"/>
</int:channel>
  1. Поскольку самый первый оператор в моей цепочке обработки сообщений перекрыл заголовок errorChannel:
<int:header-enricher>
            <int:header name="errorChannel" value="errorChannel1"/>
</int:header-enricher>
  1. Изменен параметр 'int: exception-type-router':
<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>
  1. Изменены объявления каналов получателей:
<int:channel id="handleRedirectChannel">
     <int:queue capacity="50"/>
</int:channel>

<int:channel id="surrChannelMain">
     <int:queue capacity="50"/>
</int:channel>
  1. В моем тесте я начал "слушать" errorChannel1 по каналам handleRedirectChannel.

Пока никаких следов моих закинутых исключений нет. Я подозреваю, что существует еще несколько правил, позволяющих отловить исключение, но я не могу их понять.

Еще одно обновление. Я выдал свое исключение вручную с помощью MessageBuilder (MessageBuilder.withPayload (new MyExceptionObjectWithNeededArguments) .build ()) и отправил его в errorChannel1. По-прежнему никакого эффекта (

Трассировка стека

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

Канал errorChannel1 был введен только для проверки этой проблемы. Нет других потребителей, кроме этого «маршрутизатора исключительного типа».

Исключение генерируется следующим образом:

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());

Объявление канала ошибки:

private final QueueChannel errorChannel;

@Autowired
public IntentsService(@Qualifier("errorChannel1") QueueChannel errorChannel) 
{
        this.errorChannel = errorChannel;
}

person user1053031    schedule 16.02.2021    source источник
comment
Вы можете и должны отредактировать свой вопрос, включив в него любую информацию, которая может помочь другим ответить на него. Было бы лучше, если бы вы могли переместить информацию в своем комментарии к своему вопросу.   -  person CryptoFool    schedule 16.02.2021
comment
Вероятно, у вас возникла ошибка после маршрутизации, поэтому было бы здорово увидеть это в вашем вопросе   -  person Artem Bilan    schedule 16.02.2021
comment
Вообще-то, нет. Я запускаю свою цепочку в модульном тесте и в конце пытаюсь прочитать сообщение из канала. Другой тест без исключений проходит нормально, но этот дает сбой: маршрутизации не происходит   -  person user1053031    schedule 17.02.2021


Ответы (2)


Я думаю, что вы запутались, потому что <int:exception-type-router> может иметь дело с трассировкой стека для отслеживания ожидаемого исключения, но datatype на канале - это точный тип полезной нагрузки.

См. Документы для получения дополнительной информации:

https://docs.spring.io/spring-integration/docs/current/reference/html/message-routing.html#router-implementations-exception-router

https://docs.spring.io/spring-integration/docs/current/reference/html/core.html#channel-datatype-channel

Я бы сказал, что вам не нужен datatype для этого handleRedirectChannel, поскольку вы используете его только с этого маршрутизатора. Смысл datatype в том, чтобы ограничить производителей для этого канала, что имеет смысл, когда наше приложение достаточно сложное и может работать даже в распределенном состоянии, когда мы не можем контролировать производителей. Это не похоже на случай вашего маршрутизатора исключений ...

person Artem Bilan    schedule 16.02.2021
comment
Привет, Артем! Большое спасибо за ваши предложения. К сожалению, это не помогло (похоже, что механизм перехвата не работает вообще или он был каким-то образом сломан. Я собираюсь обновить исходный пост, чтобы отразить мои недавние обновления. - person user1053031; 17.02.2021
comment
По-прежнему не понимаю, что происходит с вашим приложением. Есть ли шансы, что вы сможете поделиться с нами простым проектом, чтобы мы могли воспроизвести и поиграть с ним? Таким образом, мы сможем отладить ваш поток и посмотреть, что происходит. - person Artem Bilan; 17.02.2021
comment
Обещать это сложно. На самом деле я работаю над корпоративным приложением и, конечно, не могу им поделиться. Подготовка образца аналогичного проекта займет некоторое время, и теперь я вышла за рамки проекта из-за этой проблемы ((. Возможно, вы знаете некоторые подсказки по отладке / диагностике, помогающие точно выяснить, где и почему сообщения отправляются непосредственно на 'errorChannel1 'потеряны? Спасибо за вашу помощь - person user1053031; 17.02.2021
comment
Вы можете включить уровень ведения журнала DEBUG для категории org.springframework.integration, чтобы увидеть, как ваше сообщение перемещается в потоке. Вы можете установить точку останова в ErrorMessageExceptionTypeRouter.getChannelKeys(), чтобы увидеть, что происходит с вашим сообщением. Вероятно, в ваших журналах уже есть трассировка стека, которой вы не делитесь с нами, чтобы получить дополнительную информацию. То, что вы показываете в своей конфигурации и объясняете, должно работать. Нам не хватает некоторых деталей, которыми вы не делитесь с нами. Возможно, у вас больше потребителей на этом errorChannel1, поэтому ваше сообщение отправляется туда, а не на этот маршрутизатор. И так далее. - person Artem Bilan; 17.02.2021
comment
Спасибо. Через пару минут я предоставлю трассировку стека. Остальные дела проверю завтра утром - person user1053031; 17.02.2021
comment
Готово с трассировкой стека - person user1053031; 17.02.2021
comment
Не похоже, что эта трассировка стека как-то связана с тем, что вы показываете с помощью маршрутизатора. Если только вы не напортачили с SurrogateRoutingException и _2 _... - person Artem Bilan; 17.02.2021
comment
Вы правы: это одно и то же. Поначалу не хотелось вставлять точные имена. Мои извинения, если это был беспорядок ( - person user1053031; 17.02.2021
comment
Я не знаю. Вероятно, ваш SurrRoutingException не _2 _... Потому что это первое условие в _3 _... - person Artem Bilan; 17.02.2021
comment
На самом деле это RuntimeException. - person user1053031; 17.02.2021
comment
Хорошо, в любом случае большое спасибо за вашу помощь. Завтра я проверю остальные ваши предложения из вашего комментария выше. - person user1053031; 17.02.2021
comment
OK. Что произойдет, если вы измените default-output-channel="nullChannel" на что-то ценное? Я имею в виду, как насчет того, чтобы не игнорировать не маршрутизированные сообщения, а выгружать их в какой-то другой канал, а не на нуль - person Artem Bilan; 17.02.2021
comment
Так оно и было. Вместо nullChannel я использовал входной канал с определенным типом данных (не связанный ни с одним Throwable). Я надеялся поймать ошибку несоответствия типа или что-то в этом роде. Но ничего не было. Как черная дыра для входящего сообщения с метательной полезной нагрузкой - person user1053031; 17.02.2021
comment
OK. Как это работает, если ваш errorChannel1 не queue? Но какой смысл в том, чтобы все каналы в вашем приложении были очередями? - person Artem Bilan; 17.02.2021
comment
Потому что без queue я не могу автоматически подключать переменные QueueChannel в моем корпоративном и тестовом коде - person user1053031; 17.02.2021
comment
Хм? Это просто MessageChannel для отправки. Больше тебе ничего не нужно. Фреймворк позаботится о вас о правильной подписке, если это так. Более того, если он установлен по умолчанию DirectChannel, вы получите исключение, которое будет отброшено обратно в ваш код, когда вы отправите его errorChannel1 и что-то не так с подписчиком этого канала. Когда это очередь, обработка происходит в другом запланированном потоке. Итак, ваш тестирующий код должен каким-то образом блокировать процесс обработки. - person Artem Bilan; 17.02.2021
comment
Он блокируется методом .receive() . Задержка варьируется до 20 секунд - person user1053031; 17.02.2021
comment
Да ... Наша дискуссия может продолжаться вечно. Вот почему гораздо проще получить от вас какой-нибудь простой воспроизводимый проект, чтобы с ним поиграть. Упомянутый тест тоже был бы отличным. - person Artem Bilan; 17.02.2021
comment
Верно. Довольно сложные вещи (у меня в логике есть другие очереди, и там все работает нормально. Проблема возникает, когда я пытаюсь перехватить свое исключение в этих exception-type-router. Я постараюсь подготовить все, если не смогу как-то отладить его. Спасибо! - person user1053031; 17.02.2021
comment
Привет, Артем. Просто быстрое обновление. В отладчике ErrorMessageExceptionTypeRouter.getChannelKeys никогда не вызывался, но ErrorMessageExceptionTypeRouter.onInit выполнялся правильно. Существуют ли какие-либо требования к exception-type-router для правильного объявления? Можно ли это как-то «спрятать»? - person user1053031; 18.02.2021
comment
onInit() вызывается один раз на этапе настройки. getChannelKeys() вызывается для каждого сообщения, обрабатываемого этой конечной точкой. Вы можете начать отладку с handle() метода. Вот почему я предложил изменить errorChannel1 на прямой канал, чтобы вы могли отлаживать его прямо из его send() метода. - person Artem Bilan; 18.02.2021
comment
Привет, Артем! Я продолжаю его отлаживать. В этом методе util.AbstractExpressionEvaluator#evaluateExpression(org.springframework.expression.Expression, org.springframework.messaging.Message<?>, java.lang.Class<T>) я ловлю свой объект SurrogateRoutingException в предложении Exception (не в предложении EvaluationException). После этого этот метод выдает MessageHandlingException исключение. Я добавил этот тип исключения в свой int:exception-type-router, но это не помогло. Вы знаете, как я могу это поймать? Кажется, я немного ближе к решению. Спасибо за помощь! - person user1053031; 18.02.2021
comment
Не похоже, что это связано с отправкой исключения на канал напрямую ... - person Artem Bilan; 18.02.2021
comment
Ok. Сегодня я прокомментировал свой int:exception-type-router на основе xml и представил аннотацию, созданную с помощью аннотации @Router. По-прежнему никакого эффекта. В журналах я вижу его инициализацию, но на самом деле это не работает. По какой-то причине эта функция SI неявно отключена в моем приложении, и трудно определить, что происходит под капотом. У меня есть обработчики @Exceptionhandler, но не похоже, что это может помешать потоку выполнения приложения. - person user1053031; 18.02.2021
comment
Вы слишком много смешиваете и немного сбиваете с толку. Было бы здорово, если бы вы предоставили простой проект для экспериментов. Но, как вы объясняете, он действительно должен потерпеть неудачу. Возможно, с помощью детских шагов для воспроизведения вы увидите в своем проекте что-то еще, чем вы не делитесь с нами в данный момент. - person Artem Bilan; 18.02.2021
comment
Привет, Артем! Я добавил комментарий к этой теме. Вы можете на это посмотреть? Спасибо - person user1053031; 25.03.2021
comment
Я не знаю, как помочь вам в этом, поскольку эта информация не имеет отношения к вашему вопросу. Вы утверждаете, что ваш роутер не работает, но мы до сих пор не видим никаких доказательств этого. Если вы полагаетесь на значение по умолчанию TaskScheduler, то оно снабжено errorChannel, чтобы выявлять проблемы в его задачах. В противном случае только простой воспроизводимый проект может помочь нам определить причину. - person Artem Bilan; 25.03.2021

Я снова вернулся к этому вопросу. Еще не создал образец проекта, но нашел информацию в документации. Обработка ошибок SI: Здесь важнее всего понять, что обработка ошибок на основе обмена сообщениями применяется только к исключениям, которые генерируются задачей Spring Integration, которая выполняется в TaskExecutor. Это не относится к исключениям, создаваемым обработчиком, который работает в том же потоке, что и отправитель (например, через DirectChannel, как описано ранее в этом разделе).

Может в этом проблема? Логика моего приложения разделена между различными цепочками и маршрутами, и, возможно, некоторые из них выполняются не в TaskExecutor, и из-за этого глобальный перехват не работает? Я предполагаю, что одного перехватчика глобального масштаба для всего приложения недостаточно. Я собираюсь проверить это предположение. Спасибо!

person user1053031    schedule 25.03.2021