For example, there is a method that always throws error as shown below
private Mono myMethod() {
return Mono.error(new MyCustomException("My error"));
}
There are four useful methods in Reactor for handling error: doOnError
, onErrorMap
, onErrorReturn
, and onErrorResume
. All of them have different usage, but they have a similarity. Those methods allows us to filter which errors it should handle, either by passing the error class to be handled as the first argument or by passing Predicate
as the first argument.
If you need to handle different kinds of errors in different ways, you can call the method multiple times in chain. For example, if you want to use onErrorReturn
and you need to return different values for different errors, you can do like this:
Mono.defer(() -> myClass.myMethod())
.onErrorReturn(MyFirstException.class, "First fallback value")
.onErrorReturn(MyCustomException.class, "Fallback value")
.subscribe(System.out::println)
Because the method throws MyCustomException
, the first onErrorReturn
will be ignored as it doesn’t match.
doOnError
doOnError
will be executed when an error is thrown and hasn’t been caught. If the error has already been caught beforehand, it will not be executed. For example, the code below will print the error message (instead of the default which prints stack trace). However, the error is not caught which means you can still get the error on the next method in chain.
Mono.defer(() -> myClass.myMethod())
.doOnError(e -> e.getMessage().equals("My error"), e -> System.err.println("err:" + e.getMessage()))
.subscribe(System.out::println)
Filter by class:
Mono.defer(() -> myClass.myMethod())
.doOnError(MyCustomException.class, e -> System.err.println("err:" + e.getMessage()))
.subscribe(System.out::println)
Filter by Predicate
Mono.defer(() -> myClass.myMethod())
.doOnError(e -> System.err.println("err:" + e.getMessage()))
.subscribe(System.out::println)
onErrorMap
onErrorMap
is used to map an error into another error. As it’s only being mapped, the error is still thrown.
Mono.defer(() -> myClass.myMethod())
.onErrorMap(original -> new MyAnotherException("Not found"))
.subscribe(System.out::println)
Filter by class:
Mono.defer(() -> myClass.myMethod())
.onErrorMap(MyCustomException.class, original -> new MyAnotherException("Not found1"))
.subscribe(System.out::println)
Filter by Predicate
Mono.defer(() -> myClass.myMethod())
.onErrorMap(e -> e.getMessage().equals("My error"), original -> new MyAnotherException("Not found3"))
.subscribe(System.out::println)
onErrorReturn
With onErrorReturn
, we can set a fallback value that will be returned if error is thrown. The next method in the chain will get the fallback value instead of error.
Mono.defer(() -> myClass.myMethod())
.onErrorReturn("Fallback value")
.subscribe(System.out::println)
Filter by class:
Mono.defer(() -> myClass.myMethod())
.onErrorReturn(e -> e.getMessage().equals("My error"), "Fallback value")
.subscribe(System.out::println)
Filter by Predicate
Mono.defer(() -> myClass.myMethod())
.onErrorReturn(MyCustomException.class, "Fallback value")
.subscribe(System.out::println)
onErrorResume
With onErrorReturn
, we can set a fallback method that will be executed if error is thrown. The next method in the chain will get the result of the fallback method instead of error.
Mono.defer(() -> myClass.myMethod())
.onErrorResume(e -> myClass.fallbacKMethod())
.subscribe(System.out::println)
Filter by class:
Mono.defer(() -> myClass.myMethod())
.onErrorResume(MyCustomException.class, e -> myClass.fallbacKMethod())
.subscribe(System.out::println)
Filter by Predicate
Mono.defer(() -> myClass.myMethod())
.onErrorResume(e -> e.getMessage().equals("My error"), e -> myClass.fallbacKMethod())
.subscribe(System.out::println)
#reactjs