i am trying to suppress MessageHandlingException generated from http outbound gateway for non 2XX status codes and gracefully return back the control to the parent flow so that message with original payload is given back on the reply channel as intended in success flow.
original code :
@Bean
public IntegrationFlow inquiry() {
return flow -> flow
.handle(Http
.outboundGateway("url", restTemplate)
.mappedRequestHeaders("*")
.headerMapper(headerMapper)
.extractPayload(true)
.httpMethod(HttpMethod.POST)
.expectedResponseType(expectedResponseType.class)
)
i tried with errorHandler
on Http, but it gives a handle to the client response and original payload is not part of it.
Tried Expression Advice route as well.
@Bean
public IntegrationFlow inquiry() {
return flow -> flow
.handle(Http
.outboundGateway("url", restTemplate)
.mappedRequestHeaders("*")
.headerMapper(headerMapper)
.extractPayload(true)
.httpMethod(HttpMethod.POST)
.expectedResponseType(expectedResponseType.class)
, c->c.advice(expresionAdvice()))
The advice is not returning back the control if there is no success & failure channel, but the intention is return back the control to parent.
Probably the easiest way is to wrap the .handle with try.. catch
and catch the MessageHandlingException and propagate it to @ExceptionHandler
and transform it.
is there a way can it be done with advice or errorChannel, tried errorChannel on the @MessagingGateway
it not getting invoked after a 404 from http outbound gateway.
The above code is part of another flow and am testing this flow independently.
can there be a error channel at the integrationFlow ?
Update 1:
was able to figure out why errorChannel on @MessagingGateway
is not getting invoked from the test, it is only getting invoked when the complete flow is called rather than only inquiry()
method using DirectChannel.
Now that the errorChannel is working , have set a custom header using the payload state that was before the exception and access it back from the failedMessage Headers.
it is working as expected now and never throws an error back to the response. Feel like it is a work around..
is there a way can this be better handled in advice ?
EDIT 1:
The code is not complete i was trying out to make it work
@Bean
public Advice expressionAdvice() {
ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
advice.setOnSuccessExpressionString("payload");
advice.setOnFailureExpressionString("payload");
advice.setTrapException(true);
return advice;
}
Since i have not specified the channel flow from advice, the flow is nowhere to go, need some thing like .defaultOutputToParentFlow()
so that it goes back to the parent flow with the Message
.
Answer :
It worked, But the the only catch is, i still need the custom header to get the original payload rather than request failure payload/body for the process to continue.
@Bean
public Advice expressionAdvice() {
ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
advice.setOnSuccessExpressionString("payload");
advice.setOnFailureExpressionString("headers['CUSTOM_KEY']");
advice.setTrapException(true);
advice.setReturnFailureExpressionResult(true);
return advice;
}
This is what i was looking. May be change the variable name as the advice will return on success as well not just failure cases.
expresionAdvice()
bean. – Gary Russell