1

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?

tekumara
  • 8,357
  • 10
  • 57
  • 69

2 Answers2

3

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

Community
  • 1
  • 1
Odomontois
  • 15,918
  • 2
  • 36
  • 71
2

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.

tekumara
  • 8,357
  • 10
  • 57
  • 69
  • 2
    Well, you can write `case Failure(ex) => ex match { case ex: StatsException => ...; case ex: FileNotFoundException => ...; }; System.exit(1)`, almost like you tried initially. – Vladimir Matveev May 15 '15 at 09:33