I wrote a small error handler. When an Exception appears, I do not interrupt the processing of the request, but only return false.
When there is no error, the flatmap method takes the value received from the call - service.existsByName(name) (true or false).
public Mono<User> process(String name, User userDetails) {
return service.existsByName(name)
.doOnError(WebClientRequestException.class,
throwable -> {
log.error("Failed to find...");
}
)
.onErrorResume(ex -> Mono.just(Boolean.FALSE))
.flatMap(
isFound -> runUpdateColumn(userDetails,isFound)
);
}
public Mono<User> runUpdateColumn(userDetails,isFound){
if(isFound){
service.updateColum(false);
return Mono.just(userDetails);
}else{
service.updateColum(true);
return Mono.just(userDetails);
}
Of course, when I get true, the update of the required field goes in the normal order.
However, I lack the understanding that when false comes in a method downstream (flatMap), I would like to know that this value is received due to an error that occurred upstream (because if I get false, I also update the required field.).
Who has any ideas how to organize it?
You can "short" following operations by returning an empty publisher instead:
public Mono<User> process(String name, User userDetails) {
var potentiallyEmptyUser = service.existsByName(name)
.doOnError(WebClientRequestException.class, this::logError)
.onErrorResume(ex -> Mono.empty())
.flatMap(isFound -> runUpdateColumn(userDetails,isFound));
return potentiallyEmptyUser;
}
Executing a flatMap
over an empty publisher will produce a no-op, as no value is present to be transformed.
Beware that the above strategy will propagate empty value, so consumers would receive an empty mono instead of a user.
If you always want a default value, then you can use defaultIfEmpty
or switchIfEmpty
methods, to force a return value in case of error.
For example, you could return input user as is :
return potentiallyEmptyUser.defaultIfEmpty(userDetails);