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?
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.
In general, throw
works just like Mono.error()
(Reactor catches your exception and transforms it into a Mono.error
). The example above does not work because the exception is thrown during the assembly period before Mono
is created.