Spring Integration ошибка придает завершенную полезную нагрузку

У меня есть слушатель JMS. После прочтения сообщения я преобразую его в свой объект

public IntegrationFlow queueProcessorFlow() {
        return IntegrationFlows.from(Jms.inboundAdapter(jmsTemplate)

                        .destination("test_queue"),
                c -> c.poller(Pollers.fixedDelay(5000L)
                        .maxMessagesPerPoll(1)))

                //convert json to our custom object
                .transform(new JsonToQueueEventConverterTransformer(springBeanFactory))

                .transform(new CustomTransformer(springBeanFactory))


                .handle(o -> {


                }).get();
    }

Трансформатор

public class CustomerTransformer implements GenericTransformer<CustomPojo, CustomPojo> {


    private final QueueDataProcessorSpringBeanFactory factory;


    @Override
    public CustomPojo transform(CustomPojo CustomPojo) {
        try {

           //do something e.g. service call
           throw new Exception("This failed mate !! SOS");
        } catch (Exception e) {            

        //ISSUE here 
        //e contains the original payload in the stack trace 
            throw new RuntimeException(e);
        }
        return CustomPojo;

    }

Теперь, когда я создаю свое собственное исключение, трассировка стека содержит все. Он даже содержит полезную нагрузку. Я не заинтересован в полезной нагрузке в случае исключения.

Как мне обновить, чтобы не включать полезную нагрузку?

** Обновление **

После изменения согласно ответу я все еще вижу проблему

org.springframework.integration.transformer.MessageTransformationException: Failed to transform Message; nested exception is org.springframework.messaging.MessageHandlingException: nested exception is org.springframework.integration.transformer.MessageTransformationException: Error initiliazing the :; nested exception is CustomException Error lab lab lab  , failedMessage=GenericMessage [payload=

мой обработчик ошибок

 @Bean
    public IntegrationFlow errorHandlingFlow() {
        return IntegrationFlows.from("errorChannel")
                .handle(message -> {
                    try {

                        ErrorMessage e = (ErrorMessage) message;
                        if (e.getPayload() instanceof MessageTransformationException) {
                            String stackTrace = ExceptionUtils.getStackTrace(e.getPayload());
                            LOG.info("Exception trace {} ", stackTrace);

1 ответ

Решение

Не уверен, какова цель бизнеса потерять payload в трассировке стека, но вы можете добиться этого бросая MessageTransformationException вместо этого RuntimeException,

Чтобы избежать сообщения в трассировке стека с упомянутой полезной нагрузкой, вам нужно использовать один из этих конструкторов:

public MessageTransformationException(String description, Throwable cause) {
    super(description, cause);
}

public MessageTransformationException(String description) {
    super(description);
}

Вместо тех, которые основаны на Message<?>,

Таким образом, упаковка MessageTransformingHandler сделаем соответствующую логику:

protected Object handleRequestMessage(Message<?> message) {
    try {
        return this.transformer.transform(message);
    }
    catch (Exception e) {
        if (e instanceof MessageTransformationException) {
            throw (MessageTransformationException) e;
        }
        throw new MessageTransformationException(message, "Failed to transform Message", e);
    }
}

ОБНОВИТЬ

Оказалось, что MessageTransformationException недостаточно, так как AbstractMessageHandler проверяет на MessageHandlingException для упаковки в IntegrationUtils.wrapInHandlingExceptionIfNecessary(), Поэтому предлагаю бросить MessageHandlingException вместо вашего кода. И использовать этот конструктор с null для сообщения arg:

MessageHandlingException(Message<?> failedMessage, Throwable cause)

У меня была почти такая же проблема, возможно, это может вам помочь. Если вы используете значение по умолчаниюerrorChannel Бин уже подписан на LoggingHandler который печатает полное сообщение, если вы не хотите печатать полезную нагрузку, вы можете создать свой собственный errorChannel таким образом вы переопределите поведение по умолчанию

    @Bean
    @Qualifier(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)
    public MessageChannel errorChannel() {
        return new PublishSubscribeChannel();
    }

Если ваша проблема в том, когда вы используете .log() обработчик, вы всегда можете использовать функцию, чтобы решить, какую часть сообщения вы хотите показать

  @Bean
  public IntegrationFlow errorFlow(IntegrationFlow 
    createOutFileInCaseErrorFlow) {
    return 
    IntegrationFlows.from(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)
   .log(LoggingHandler.Level.ERROR, m -> m.getHeaders())
   .<MessagingException>log(Level.ERROR, p -> p.getPayload().getMessage())
   .get();
  }
Другие вопросы по тегам