I'm trying to work out a WebClient
based approach to handling and enrichment using a sub-flow on a WebFlux.outboundGateway
call.
My intent is to handle the case where an HTTP/404 occurs on the remote end. In that case, I will handle the error with a known document which can be handled down-stream and routed appropriately.
.enrich( e ->
e.requestSubFlow(
sf -> sf.handle(
WebFlux.outboundGateway("http://example.com/entity/name/{entityName}")
.uriVariable("entityName", "payload")
.httpMethod(HttpMethod.GET)
.expectedResponseType(String.class),
ec -> ec.customizeMonoReply(
(message,mono) ->
mono.onErrorResume(
WebClientResponseException.NotFound.class,
Mono.just("{ \"id\": -1, \"name\": null }")
.flatMap(s ->
ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(s)
)
)
)
)
)
.headerExpression("result", "payload")
)
What I'm getting is a compilation error similar to the following:
The method onErrorResume(Class<E>, Function<? super E,? extends Mono<? extends capture#3-of ?>>) in the type Mono<capture#3-of ?> is not applicable for the arguments (Class<WebClientResponseException.NotFound>, Mono<Object>)
I don't even know if I am approaching this correctly. Any advice would be greatly appreciated.
In order to help with this I've posted the entire code https://github.com/djgraff209/so68637283.
EDIT 8/6:
Thanks to @artem-bilan for feedback on this. First point was that the second argument to onErrorResume
was not a function. I have corrected that.
Next up, the exception match turned out to be incorrect. A generic WebClientResponseException
was being thrown rather than a more specific WebClientResponseException.NotFound
which is what I was hoping for.
I updated the logic as follows. This code is available on the referenced GitHub project.
ec -> ec.customizeMonoReply(
(Message<?> message, Mono<?> mono) ->
mono.onErrorResume(
WebClientResponseException.class,
ex1 -> {
Mono<?> exReturn = mono;
if( ex1.getStatusCode() == HttpStatus.NOT_FOUND ) {
exReturn = Mono.just(defaultPayload);
}
return (Mono)exReturn;
}
)
)
While this works, it is not as clean as I would like. I am not thrilled with having to put an if condition in there to resolve the exception type by the HttpStatus
rather than just resolve it to the specific class.
This might be a good candidate for a bug/enhancement.
Submitted #3610
I think it must be like this:
mono.onErrorResume(
WebClientResponseException.class,
ex1 -> Mono.just(ex1)
.filter(ex -> ex.getStatusCode() == HttpStatus.NOT_FOUND)
.map(ex -> "default")
.switchIfEmpty((Mono) mono))
The second argument of onErrorResume()
is expected to be a Function
, not a constant as you have so far.