tekumara
tekumara

Reputation: 8807

How to handle different cases of Failure from Try

I want to handle different cases of Failure (returned as Try).

example code

main(args(0)) match {
  case Success(result) => result.foreach(println)
  case Failure(ex) => ex match {
    case FileNotFoundException =>
      System.err.println(ex.getMessage)
    case StatsException =>
      System.err.println(ex.getMessage)
    case _ => {
      ex.printStackTrace()
    }
      System.exit(1)
  }
}

If its a StatsException or FileNotFoundException just print the message, for all other exceptions print a stack trace.

However ex is only ever a Throwable, and so case StatsException is a fruitless type test (a value of type Throwable cannot also be a StatsException.type according to IntelliJ)

Worse I get compile errors: java.io.FileNotFoundException is not a value

What's the best way to handle different cases of Failure in an idiomatic way?

Upvotes: 1

Views: 1137

Answers (2)

Odomontois
Odomontois

Reputation: 16308

I would simplify your own answer:

main(args(0)) map (_ foreach println) recover {
  case ex@(_: FileNotFoundException | _: StatsException) =>
    System.err.println(ex.getMessage)
    System.exit(1)
  case ex =>
    ex.printStackTrace()
    System.exit(1)
}

In the first case clause we are matching two alternative. scala forbids declarations like case ex: FileNotFoundException | ex: StatsException, but we could assign whole match result via @ symbol. See this question for more details

Upvotes: 3

tekumara
tekumara

Reputation: 8807

This seems to work:

main(args(0)) match {
  case Success(result) => result.foreach(println)
  case Failure(ex: FileNotFoundException) =>
    System.err.println(ex.getMessage)
    System.exit(1)
  case Failure(ex: StatsException) =>
    System.err.println(ex.getMessage)
    System.exit(1)
  case Failure(ex) =>
    ex.printStackTrace()
    System.exit(1)
}

Would be nice to have the System.exit(1) call shared by all Failure cases.

Upvotes: 2

Related Questions