Issue
I have 3 micro-service applications. I am trying to do 2 get call async using webclient from reactive package and then combine them whenever I get a response.
Sample code for that: (referred from - https://docs.spring.io/spring/docs/5.1.9.RELEASE/spring-framework-reference/web-reactive.html#webflux-client-synchronous)
Mono<Person> personMono = client.get().uri("/person/{id}", personId)
.retrieve().bodyToMono(Person.class);
Mono<List<Hobby>> hobbiesMono = client.get().uri("/person/{id}/hobbies", personId)
.retrieve().bodyToFlux(Hobby.class).collectList();
Map<String, Object> data = Mono.zip(personMono, hobbiesMono, (person, hobbies) -> {
Map<String, String> map = new LinkedHashMap<>();
map.put("person", personName);
map.put("hobbies", hobbies);
return map;
})
.block();
My question is how can I add exception handling to the get calls?
How do I check if I got a 404 or 204 or something else?
I have tried:
- Adding .onStatus() to the GET calls
.onStatus(HttpStatus::is4xxClientError, clientResponse ->
Mono.error(new Data4xxException(String.format(
"Could not GET data with id: %s from another app, due to error:
%s", key, clientResponse))))
.onStatus(HttpStatus::is5xxServerError, clientResponse ->
Mono.error(new Data5xxException(
String.format("For Data %s, Error Occurred: %s", key, clientResponse))))
- Adding exceptionhandlers - but I exactly dont have a controller so this does not seem to be working.
@ExceptionHandler(WebClientException.class)
public Exception handlerWebClientException(WebClientException webClientException) {
return new Data4xxException("Testing", webClientException);
}
- Added a class with ControllerAdvice and ExceptionHandler within it
@ControllerAdvice
public class WebFluxExceptionHandler {
@ExceptionHandler(WebClientException.class)
public Exception handlerWebClientException(WebClientException webClientException) {
return new Data4xxException("Testing", webClientException);
}
}
But I don't see them printed in the spring-boot logs.
The Mono.zip.block() method just returns null and does not actually throw any exception.
How do I get the zip method to throw the exception and not return null ?
Solution
The way to do it is using onErrorMap in the following way:
Mono<Person> personMono = client.get()
.uri("/person/{id}", personId)
.retrieve()
.bodyToMono(Person.class)
.onErrorMap((Throwable error) -> error);
onErrorMap will make the Mono to actually throw an error when Zip blocks, terminating zip and letting spring or any other class that you want to handle the exception.
Answered By - Harshad Loya
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.