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

空的 catch 块在 Scala 中似乎无效

try {
  func()
} catch {

} // error: illegal start of simple expression

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

【问题讨论】:

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

标签: scala exception functional-programming try-catch


【解决方案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()}
          

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

          【讨论】:

            猜你喜欢
            • 2011-02-13
            • 1970-01-01
            • 1970-01-01
            • 2018-11-01
            • 2011-11-09
            • 1970-01-01
            • 1970-01-01
            • 2022-11-23
            • 1970-01-01
            相关资源
            最近更新 更多