I'm working on a Spring webflux project and I want to understand the difference between throwing an exception vs using Mono.error().
If there is a validation class like this for example:
public class NameValidator {
public static boolean isValid(String name) {
if(StringUtils.isEmpty(name)) {throw new RuntimeException("Invalid name");}
return true;
}
}
public class NameValidator2 {
public static Mono<Object> isValid(String name) {
if(StringUtils.isEmpty(name)) {
return Mono.error(new RuntimeException("Invalid name"));}
return Mono.just(true);
}
}
What are the pros & cons with each approach. When to use one over the other while working with reactive streams using spring webflux?
CodePudding user response:
Basically you will have the same result in the end and no difference between the two options (maybe performance wise but I have not found anything backing this opinion so I guess it can be negligible. The only “difference” is that Mono.error follows the Reactive Streams specification and throwing an exception as is does not (read more at https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.3/README.md#2.13). However it is not prohibited, but if you like to follow standards and specifications (I guess you do) you should consider using Mono.error.
CodePudding user response:
As @Joao already stated, the recommended way to deal with an error is to call the error
method on a Publisher
(Mono.error
/Flux.error
).
I would like to show you an example in which the traditional throw
does not work as you may expect:
public void testErrorHandling() {
Flux.just("a", "b", "c")
.flatMap(e -> performAction()
.onErrorResume(t -> {
System.out.println("Error occurred");
return Mono.empty();
}))
.subscribe();
}
Mono<Void> performAction() {
throw new RuntimeException();
}
The onErrorResume
operator will never be executed because the exception is thrown before Mono
is assembled.