user1870400
user1870400

Reputation: 6364

How to catch a specific runtime exception using Vavr (formerly known as Javaslang) library?

I am trying to catch a specific runtime exception (so not throwable) and just log it (log.error has a void return type). What is the simplest way to do this in vavr?

try {
    sayHello();
} catch (MyAppRuntimeException ex) {
    log.error("Error occured") // log.error returns void not Void so I couldn't find a suitable method in  Vavr library
}

I have tried

Try.run(() -> sayHello())
   .recover(MyAppRuntimeException.class, ex->log.error("Error occured: {}", ex.getMessage()))

I get:

Bad return type void cannot be converted to Void

If .recover is not the right method please suggest alternatives where I can catch my one specific Exception but not Throwable since it catches all exceptions and errors.

Upvotes: 6

Views: 8835

Answers (1)

Opal
Opal

Reputation: 84784

It's quite easy to explain. You method - it isn't stated explicitly but I assume so based on error message returns void. Since recover also must return a value - needed for further processing - compatible with the type returned from methods it wraps, it has to return Void, so:

So the code will be:

Try
   .run(this::sayHello)
   .recover(MyAppRuntimeException.class, e -> {
      log.error("Error occured: {}", e.getMessage());
      return null;
   });

Have a look at the docs.

EDIT

After discussion in comments it turned out that recover is not what is needed. This function is used to provide a recovery value, not to log a statement, hence onFailure + instanceof (instead of pattern matching) seems to do the job:

Try
   .run(this::sayHello)
   .onFailure(throwable -> {
      if (throwable instanceof MyAppRuntimeException) {
         log.error("Error occured: {}", throwable.getMessage());
      } else {
         throw new RuntimeException(throwable);
      }
   })

Upvotes: 4

Related Questions