Scala:静默捕获所有异常

Posted

技术标签:

【中文标题】Scala:静默捕获所有异常【英文标题】:Scala: Silently catch all exceptions 【发布时间】:2014-02-05 20:44:10 【问题描述】:

空的 catch 块在 Scala 中似乎无效

try 
  func()
 catch 

 // error: illegal start of simple expression

如何在不处理的情况下捕获所有异常?

【问题讨论】:

默默地吞下异常是个坏主意——当出现问题时,你永远不会知道。至少记录异常。 @Jesper 有时你真的不想知道。而且你不想让你的老板知道。 【参考方案1】:

有些异常确实不应该被捕获。无论如何你都可以要求它:

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 效果不佳。)

【讨论】:

这真的需要一张猫图:默默捕捉所有异常! +1 致所有 cmets 关于不为 ALL Throwable 实例执行此操作。忽略一些 JVM 错误,例如 OutOfMemoryError,可能会使 JVM 处于不一致的状态,从而导致极难诊断的细微错误,并有可能导致静默数据损坏(取决于程序)。 @KristianDomagala 原因不仅仅是JVM异常,比如OOM之类的,问题是有一组exceptions which scala is using for control flow。 你的意思是catch case NonFatal(t) => ,加上额外的case 这种情况下如何打印catch case _: Throwable => 【参考方案2】:

import scala.util.Try

val res = Try (func()) toOption 

如果尝试成功,您将获得Some(value),如果失败则获得None

【讨论】:

【参考方案3】:

尝试添加

case x =>

在你的 catch 块中:)

【讨论】:

这也会捕获控制异常,这通常是一个非常糟糕的情况。【参考方案4】:

在 Scala 的 catch 块中,您需要使用与 match 语句中类似的构造:

try 
  func()
 catch 
  case _: Throwable => // Catching all exceptions and not doing anything with them

【讨论】:

警告:这会捕获所有 Throwables。如果确实如此,请使用case _ : Throwable 清除此警告。当我改为添加 case _ : Throwable 时,它不会编译:错误:'=>' 预期但 '' 找到 @tmporaries 你需要箭头。你应该写case _: Throwable =>来表达你不是偶然的。 @som-snytt 谢谢,你是对的。使用 Throwable 更新答案。【参考方案5】:

如果用 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

【讨论】:

【参考方案6】:

为了完整起见,有一个set of built-in methods in Exception,包括静默捕获异常。使用详情请见Using scala.util.control.Exception。

【讨论】:

【参考方案7】:

我喜欢这里的建议之一,将 Try()toOption 一起使用,但如果您不想进一步使用 Option,您可以这样做:

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

【讨论】:

【参考方案8】:

怎么样:

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

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

【讨论】:

以上是关于Scala:静默捕获所有异常的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中报告静默崩溃

如何在 iOS 的 UAPushNotificationDelegate 上捕获后台静默推送通知?

任务和异常静默

Atitit 错误处理机制:静默模式警告模式 异常模式

这是静默忽略Ruby异常的最短方法

Django:自定义模板简单标签应该引发异常还是静默失败?