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