I've got a scenario that was caused by misconfiguration of a URL
@Bean
ExpressionEvaluatingRequestHandlerAdvice notFoundAdvice() {
final ExpressionEvaluatingRequestHandlerAdvice advice =
new ExpressionEvaluatingRequestHandlerAdvice();
advice.setOnFailureExpressionString(
"#exception.getCause()"
+ " instanceof T(org.springframework.web.client.HttpClientErrorException.NotFound)"
+ " ? '{ \"value\": null }' : payload"
);
advice.setReturnFailureExpressionResult(true);
return advice;
}
@Bean
public IntegrationFlow myIntegrationFlow(final RestTemplate restTemplate) {
return f -> f
f.enrich(
e -> e.requestSubFlow(
sf -> sf
.handle(
Http.outboundGateway(misconfiguredUrl, restTemplate)
.httpMethod(HttpMethod.GET)
.uriVariable("productId", "headers.productId")
.mappedResponseHeaders()
.expectedResponseType(String.class),
ec -> ec.advice(notFoundAdvice())
)
)
.propertyExpression("productData", "#jsonPath(payload, '$.value')")
)
);
}
Obviously this is overly contrived, but if misconfiguredUrl
were to say not include the http://host
portion of the URL, this would result in a URL failure.
I am not seeing this particular error blowing out but that the #jsonPath(...)
fails with $[value]
not found.
Is there some configuration that can be applied to log an error from the outboundGateway in this case?
EDIT:
After commentary exchange I realized that I had (1) omitted the endpoint configuration that handles the case of a "legit" 404 error (2) in doing so identified that I had set setReturnFailureExpressionResult
which was incorrect.
Removing the setReturnFailureExpressionResult
setting corrected the problem and surfaced the error.
EDIT2: So I spoke to soon and did not completely test this.
While this surfaces the error it does not allow me to trap specifically one case (404) and return a default while still allowing other calls to fail as normal with exception.
I might have to rethink the approach a little here.
EDIT3: Implemented a custom handling class
public class CustomNotFoundAdvice extends AbstractRequestHandlerAdvice {
private static final Logger log = LoggerFactory.getLogger(CustomNotFoundAdvice.class);
final Object defaultReturn;
public CustomNotFoundAdvice(final Object defaultReturn) {
this.defaultReturn = defaultReturn;
}
@Override
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) {
Object result;
try {
result = callback.execute();
}
catch(RuntimeException ex) {
final Exception realException = unwrapExceptionIfNecessary(ex);
if( realException instanceof MessageHandlingException
&& realException.getCause() instanceof HttpClientErrorException.NotFound) {
log.warn("Unable to locate object "+target);
result = defaultReturn;
}
else {
throw ex;
}
}
return result;
}
}