Affects: Spring WebFlux latest
Hi.
The java example of the new exchangeToMono method does not compile.
https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-client-exchange
ClientResponse.createException returns Mono
client.get()
.uri("/persons/1")
.accept(MediaType.APPLICATION_JSON)
.exchangeToMono(response -> {
if (response.statusCode().equals(HttpStatus.OK)) {
return response.bodyToMono(Person.class);
}
else if (response.statusCode().is4xxClientError()) {
return response.bodyToMono(ErrorContainer.class);
}
else {
return response.createException().map(exception -> Mono.error(exception));
// return response.createException();
// return Mono.error(response.createException());
}
})
.doOnError(...)
.doOnSuccess(...)
.subscribe();
I just want to fail the sequence and precieve exception within Mono.error.
Comment From: rstoyanchev
Indeed there is an issue. response.createException()
returns Mono<Exception>
which want to turn into a Mono.error(ex)
with the resolved exception, but we have to do that with .flatMap
since otherwise .map
ends up with Mono<Mono<?>>
.
So it should be response.createException().flatMap(Mono::error)
.
Comment From: windymindy
Nice!
But there is still something confusing.
If one try and compile he would get
'incompatible types: inference variable T has incompatible bounds'
'no instance(s) of type variable(s) exist so that T2 conforms to T1 inference variable V has incompatible bounds: equality constaints: T1 lower bounds: T2'
That's because of the exchangeToMono
signature.
And Person
with ErrorContainer
is not compatible.
Maybe the type has to be erased with Mono<Object>
.
This works though.
client.get()
.uri("/persons/1")
.accept(MediaType.APPLICATION_JSON)
.exchangeToMono(response -> Mono.just(response)
.flatMap(r -> {
if (response.statusCode().equals(HttpStatus.OK))
return response.bodyToMono(Person.class);
else if (response.statusCode().is4xxClientError())
return response.bodyToMono(ErrorContainer.class);
else
return response.createException().map(exception -> Mono.error(exception));
})
)
.doOnError(...)
.doOnSuccess(...)
.subscribe();
The signature difference is
<V> Mono<V> exchangeToMono(Function<ClientResponse, ? extends Mono<V>> var1)
<R> Mono<R> flatMap(Function<? super T, ? extends Mono<? extends R>> transformer)
@rstoyanchev
Comment From: rstoyanchev
It has to be Mono<Object>
because the flatMap can return different objects depending on the response.