Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala.util.Try: How to get Throwable value? Pattern matching?

The following REPL snippets presume:

import scala.util.{Try, Success, Failure}

Why do these two statements not pass compilation? I get "constructor cannot be instantiated to expected type":

Failure(new Exception("a")) match {
  case Success(i) => "a"; case Failure(e) => "b"; case _ => "c"; }

Success(123) match {
  case Success(i) => "a"; case Failure(e) => "b"; case _ => "c"; }

I can get the success value out of a Try with get or toOption. Is there a corresponding way to get the failing Throwable value or Option[Throwable]?

EDIT: Casting from Failure/Success to Try works

Failure(new Exception("a")).asInstanceOf[Try[Int]] match {
  case Success(i) => "a"; case Failure(e) => "b"; case _ => "c"; }

Success(123).asInstanceOf[Try[Int]] match {
  case Success(i) => "a"; case Failure(e) => "b"; case _ => "c"; }
like image 590
clay Avatar asked Aug 31 '14 02:08

clay


1 Answers

Consider this:

Try(1) match {
    case Success(i) => i
    case Failure(t) => 0 // t is the `Throwable`
}

This works because Success and Failure are sub classes of the abstract class Try. However, the following code fails to compile, because you're no longer matching on a generic Try, and instead a Failure which can never be an instance of Success.

Failure(new Exception("a")) match {
    case Success(i) => "a" // You can see it compiles if you remove this line.
    case Failure(e) => "b"
    case _ => "c"
}

This is like trying to match an Integer to a String, it doesn't really make sense.

If you want to get the Throwable via pattern matching, see the first snippet of code.

Another way you could extract the Throwable would be to use the failed method on your Try, which will wrap the Throwable from a failure within Success.

scala> val t: Throwable = Try(throw new Exception).failed.get
t: Throwable = java.lang.Exception

Calling this on a Success, however, will throw another exception.

like image 107
Michael Zajac Avatar answered Oct 13 '22 05:10

Michael Zajac