Scala:悄悄地捕获所有异常

17

在Scala中,空的catch块似乎是无效的。

try {
  func()
} catch {

} // error: illegal start of simple expression

我如何捕获所有异常但不对其进行处理?


2
悄悄地吞噬异常是一个坏主意 - 当出现问题时,你永远不会知道。至少记录一下异常。 - Jesper
6
@Jesper 有时候你真的不想知道。并且你也不希望你的老板知道。 - som-snytt
8个回答

38

有些异常确实不应该被捕获。但你仍然可以请求它:

try { f(x) }
catch { case _: Throwable => }

但这可能不太安全。

scala.util.control.NonFatal 匹配所有安全的异常,因此您可以:

import scala.util.control.NonFatal
try { f(x) }
catch { case NonFatal(t) => }

对于稍微不那么冒险但仍非常有用的捕获操作。

或者scala.util.Try可以为您完成:

Try { f(x) }

如果你想知道发生了什么,你可以在结果上进行模式匹配。 (但是,当你需要一个finally块时,Try并不太适用。)

3
这确实需要一张猫的图片:悄悄地捕捉所有的异常! - som-snytt
关于不要对所有“Throwable”实例执行此操作的所有评论,都要点赞。忽略一些JVM错误,如“OutOfMemoryError”,可能会使JVM处于不一致的状态,导致难以诊断且潜在引起静默数据损坏的微妙错误(取决于程序)。 - Kristian Domagala
1
@KristianDomagala,问题不仅仅是JVM异常,例如OOM或类似的异常,问题在于Scala使用一组异常来控制流程。详情请参见:http://www.tzavellas.com/techblog/2010/09/20/catching-throwable-in-scala/。 - om-nom-nom
你的意思是加上额外的 case,改为 catch { case NonFatal(t) => } 吗? - Dirk Groeneveld
在这种情况下如何打印 catch { case _: Throwable => } - nurgasemetey

5

In

import scala.util.Try

val res = Try (func()) toOption 

如果Try成功,您将得到Some(value),如果失败,则为None


3
在Scala的catch块中,您需要使用与匹配语句类似的结构:
try {
  func()
} catch {
  case _: Throwable => // Catching all exceptions and not doing anything with them
}

警告:这会捕获所有的Throwables。如果确实打算这样做,请使用case _ : Throwable来清除此警告。 但是,当我改用case _ : Throwable时,它无法编译:错误:需要' =>',但找到了'}' - tmporaries
2
@tmporaries 你需要使用箭头。你应该写case _: Throwable =>表达你不是无意中这样做的。 - som-snytt
@som-snytt 谢谢,你是对的。使用 Throwable 更新了答案。 - Akos Krivachy

3
如果使用Throwable注释很麻烦,你也可以:
scala> def quietly[A]: PartialFunction[Throwable, A] = { case _ => null.asInstanceOf[A] }
quietly: [A]=> PartialFunction[Throwable,A]

scala> val x: String = try { ??? } catch quietly
x: String = null

这有一个小优点,即自我记录。

scala> val y = try { throw new NullPointerException ; () } catch quietly
y: Unit = ()

编辑:语法更改包括try-catch中减少大括号,使用函数进行捕获和将函数字面量作为偏函数:

scala> def f(t: Throwable) = ()
def f(t: Throwable): Unit

scala> try throw null catch f
                            ^
       warning: This catches all Throwables. If this is really intended, use `case _ : Throwable` to clear this warning.

scala> def f: PartialFunction[Throwable, Unit] = _ => ()
def f: PartialFunction[Throwable,Unit]

scala> try ??? catch f

3
尝试添加

标签。

case x =>

在您的捕获块中 :)

这也会捕获控制异常,这通常是一个非常糟糕的情况。 - om-nom-nom

2

我喜欢这里的一个建议,即使用Try()toOption,但是如果您不想继续使用Option,您也可以这样做:

Try(func()) match {
  case Success(answer) => continue(answer)
  case Failure(e) => //do nothing
}

2

0

这个怎么样:

import scala.util.control.Exception.catching
catching(classOf[Any]) opt {func()}

它会生成一个像之前某些答案中的选项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接