mmm111mmm
mmm111mmm

Reputation: 4085

Scala Try and different Failure cases

This code return "I've failed" as excepted.

  Try({
    throw new Exception()
  }) match {
    case Failure(e) => println("I've failed")
    case Success(s) => println("I've succeeded")
  }

But what if I have different Exception, such as:

  Try({
    if(someBoolean) {
      throw new DifferentException()
    } else {
      throw new Exception()
    }
  }) match {
    case Failure(e) => println("I've failed")
    case Success(s) => println("I've succeeded")
  }

How do I change the match statement so that we have a different case for Exception and DifferentException?

I understand I can do this:

  Try({
    if(true) {
      throw new DifferentException()
    } else {
      throw new Exception()
    }
  }) match {
    case Failure(e) if e.isInstanceOf[DifferentException] => println("I've failed differently")
    case Failure(e) if e.isInstanceOf[Exception]          => println("I've failed")
    case Success(s) => println("I've succeeded")
  }

Is this the best, i.e least verbose, way to achieve such?

[Edit]

Thank you to Ashesh. The least verbose, for me, was this:

case class DifferentException() extends Exception() {}

Try({
  if(someBoolean) { 
    throw new DifferentException
  } else { 
    throw new Exception
  } 
}) match { 
  case Failure(DifferentException()) => println("I've failed differently")
  case Failure(e)                    => println("I've failed")
  case Success(s)                    => println("I've succeeded")
}

Upvotes: 3

Views: 3563

Answers (2)

Tzach Zohar
Tzach Zohar

Reputation: 37832

You can match Failure(e: ExceptionType) for any exception type (case class or not), no need to create your own exception types or two pattern matching expressions:

def printResult(action: => Unit) = {
  Try(action) match {
    case Failure(e: IllegalArgumentException) => println("illegal arg exception")
    case Failure(e) => println("other exception")
    case _ => println("success")
  }
}

printResult(throw new IllegalArgumentException)  // prints "illegal arg exception"
printResult(throw new RuntimeException)          // prints "other exception"
printResult(1)                                   // prints "success"

Upvotes: 7

Idkt
Idkt

Reputation: 2996

No. You can match on case class exceptions;

case class ExceptionOne(msg: String) extends Exception(msg) and so forth;

And then;

Try { /* ...*/ } match {
  case Failure(ExceptionOne(msg)) => println("exception of type 1")
  // more cases
  case Failure(e) => println("generic exception")
  case Success(s) => ???
}

Alternatively, you could match on a single Failure and do a match on the exception contained in it, so;

Try { /* ...*/ } match {
  case Failure(e) => e match {
    case e1: DifferentException => // do something with DifferentException
    case e: Exception => // do something with a generic exception
  }
  case Success(s) => ???
}

Upvotes: 1

Related Questions