0

Continuation of Error handling - no output-channel or replyChannel header available,

I am returning ResponseEntity from the transformer of ExpressionEvaluatingRequestHandlerAdvice failureChannel. when I debug I can see ResponseEntity<Object> response = <409 CONFLICT Conflict,com.practice.integration.commons.error.AdapterErrorResponse@4d5a370b,[]> and its body(AdapterErrorResponse POJO) has HttpStatus status, List<AdapterError> errors which has populated correct value that I want and as per Artem Bilan's suggestion for preserving request message headers I am sending that response as MessageBuilder.withPayload(response).copyHeaders(message.getPayload().getFailedMessage().getHeaders()).build()

and I have also configured output channel on the transformer but it still does not show the above response as a part of http response payload, output channel I have is same as reply channel of the inbound gateway. could you please help here?

and I have one more external call following the above, there also I have used different transformer to handle exception and I am sending similar ResponseEntity from there , it works fine there and send response to the reply channel of the inbound gateway. Only difference is I am not using ExpressionEvaluatingRequestHandlerAdvice for the second outbound gateway.

Do you think I should do something extra with handling response using ExpressionEvaluatingRequestHandlerAdvice or am I missing anything on the first outbound gateway?

1 Answers1

0

You probably didn't do this: ExpressionEvaluatingRequestHandlerAdvice.setTrapException(true);

Here is a working test, it is not HTTP based, but approach is exactly the same for any inbound request-reply gateway:

@SpringJUnitConfig
public class So74658669Tests {

    @Autowired
    InputGateway inputGateway;

    @Test
    void errorHandlerResultPropagatedBackToGateway() {
        assertThat(this.inputGateway.sendAndReceive("test"))
                .isEqualTo("Request failed for: test");
    }

    @Configuration
    @EnableIntegration
    @Import(InputGateway.class)
    public static class TestConfiguration {

        @Bean
        MessageChannel outputChannel() {
            return new DirectChannel();
        }

        @ServiceActivator(inputChannel = "inputChannel", outputChannel = "outputChannel", adviceChain = "requestHandlerAdvice")
        String requestAndReply(String payload) {
            throw new RuntimeException("failure");
        }

        @Bean
        ExpressionEvaluatingRequestHandlerAdvice requestHandlerAdvice() {
            ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
            advice.setFailureChannelName("errorHandlerChannel");
            advice.setTrapException(true);
            return advice;
        }

        @Transformer(inputChannel = "errorHandlerChannel", outputChannel = "outputChannel")
        Message<String> errorHandler(Message<MessagingException> errorMessage) {
            return MessageBuilder.withPayload("Request failed for: " + errorMessage.getPayload().getFailedMessage().getPayload())
                    .copyHeaders(errorMessage.getPayload().getFailedMessage().getHeaders())
                    .build();
        }

    }

    @MessagingGateway
    interface InputGateway {

        @Gateway(requestChannel = "inputChannel", replyChannel = "outputChannel")
        String sendAndReceive(String payload);

    }

}

By the way there is no need in that outputChannel at all if you don't do any extra work on reply. The framework just find a replyChannel header and sends reply message directly to the input gateway.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • thank you so much! I wish I had posted this earlier, I spend almost half a day tried and testing adding new transformers, forming new responses, different exceptions! – KeepItSimple Dec 02 '22 at 17:47
  • Docs: https://docs.spring.io/spring-integration/docs/current/reference/html/messaging-endpoints.html#expression-advice – Artem Bilan Dec 02 '22 at 18:02