Project Reactor Tutorial - Error Handling Examples

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.

Using 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)

Using 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)

Using 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)

Using 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

Project Reactor Tutorial - Error Handling Examples
18.10 GEEK