【发布时间】:2018-03-27 22:50:52
【问题描述】:
在 Scala 中,将模式匹配用于异常处理的典型用法(至少对于像 this 和 this 这样的来源而言)如下所示:
Try(...) match {
case Success(_) => println("success")
case Failure(exc) => println(s"caught: $exc")
}
但是,该模式也可以捕获try 块中抛出的任何非Exception Throwables:
Try(throw new AssertionError("assertion error")) match {
case Success(_) => println("success")
case Failure(exc) => println(s"caught: $exc")
}
caught: java.lang.AssertionError: assertion error
至少在 Java 中,在没有令人信服的理由的情况下捕获 Throwable 通常被认为是一种反模式。 (This source 为 Scala 提供了同样的建议。)
避免静默捕捉Throwable 的一种选择是捕捉它并重新抛出它:
Try(throw new AssertionError("assertion error")) match {
case Success(_) => println("success")
case Failure(exc : Exception) => println(s"caught: $exc")
case Failure(th) => throw th
}
不过,为了避免捕获非ExceptionThrowables(通常被认为是不可恢复的),并且让这样的Throwables 逃逸,这似乎很奇怪,这在 Java 风格中是隐含的try/catch 语法,必须显式实现。
是否有更简洁/惯用的语法在 Scala 中使用模式匹配进行异常处理,同时避免无意中捕获 Throwable?
【问题讨论】:
-
FWIW,
Try仅捕获 NonFatal 可投掷物。 -
@hoyland 有趣的点;如果我最初的问题的答案是“否”(不存在这样的惯用语法),也许这可以解释原因:设计者认为避免捕获
Throwable并不重要,因为他们已经区分了致命与非致命Throwables 通过NonFatal提取器。 (尽管在这种情况下,“致命”Throwables 的集合似乎是不可扩展的,这似乎很不幸。)
标签: scala exception-handling throwable