Scala.util.Try: How to get Throwable value? Match patterns?

The following REPL snippets are assumed:

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

Why don't these two statements pass compilation? I get: "the constructor cannot be created for the 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 from Try using get or toOption . Is there an appropriate way to get a Throwable or Option[Throwable] ?

EDIT: Casting from failure / success to try work

 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"; } 
+7
scala try-catch
source share
2 answers

The first fragment does not compile because Success not a subtype of Failure . The compiler thinks you're stupid, as the Success(i) case will never match.

To take a simpler example, this also does not compile.

 Failure(new Exception()) match { case Success(_) => } 

This is also for the same reason.

 42 match { case Success(_) => } 

What you wrote almost worked, but the value you match should be of a more general type, Try[_] (which would be one way or another if pattern matching was actually used in some useful context).

 (Failure(new Exception("a")): Try[_]) match { case Success(i) => "a"; case Failure(e) => "b"; case _ => "c"; } 
+11
source share

Consider this:

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

This works because Success and Failure are subclasses of the abstract Try class. However, the following code does not compile because you are no longer mapped to a common Try , but instead 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 map Integer to String , it really doesn't make sense.

If you want to get Throwable through a template, see the first code snippet.

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

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

Calling this in Success , however, will raise another exception.

+17
source share

All Articles