Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: idiomatic Try-match and avoiding catching Throwable

In Scala, a typical use of pattern matching for exception handling (at least per sources like this and this) looks like the following:

Try(...) match {
  case Success(_) => println("success")
  case Failure(exc) => println(s"caught: $exc")
}

However, that pattern also catches any non-Exception Throwables thrown in the try block:

Try(throw new AssertionError("assertion error")) match {
  case Success(_) => println("success")
  case Failure(exc) => println(s"caught: $exc")
}

caught: java.lang.AssertionError: assertion error

In Java, at least, catching Throwable without a compelling reason to do so is generally considered to be an anti-pattern. (This source offers the same counsel for Scala.)

One option to avoid silently catching Throwable is to catch it and re-throw it:

Try(throw new AssertionError("assertion error")) match {
  case Success(_) => println("success")
  case Failure(exc : Exception) => println(s"caught: $exc")
  case Failure(th) => throw th
}

It seems odd, though, that an extra re-throw is necessary to avoid catching non-Exception Throwables (usually considered unrecoverable), and that letting such Throwables escape, implicit in Java-style try/catch syntax, must be implemented explicitly.

Is there a more succinct / idiomatic syntax for using pattern-matching for exception-handling in Scala, while avoiding inadvertently catching Throwable?

like image 602
sumitsu Avatar asked Oct 18 '25 13:10

sumitsu


1 Answers

Because the recover() method takes a PartialFunction, it can be used to filter for the type of Throwable you want to handle. After that, you can let get unwrap the Try and retrieve a value if it was either a Success or a handled Failure, or it will re-throw if it's still a Failure, i.e. not handled by recover().

val result = Try{
               //code block here
             }.recover{
               case exc:Exception => ... //should return same type as Success
             }.get //unwrap the Try, will throw if Throwable was not an Exception
like image 58
jwvh Avatar answered Oct 21 '25 03:10

jwvh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!