Scala 中 NonFatal 和 Exception 的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29744462/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 07:04:34  来源:igfitidea点击:

The difference between NonFatal and Exception in Scala

scalaexception-handling

提问by null

In this article, it's said that:

这篇文章中,它说:

If you want to catch “everything” that would normally happen, then use NonFatal:

如果你想捕捉通常会发生的“一切”,那么使用 NonFatal:

import scala.util.control.NonFatal

try {
  operation()
} catch {
  case NonFatal(e) => errorHandler(e)
}

But I usually use Exception:

但我通常使用Exception

try {
  operation()
} catch {
  case e: Exception => errorHandler(e)
}

I would like to know what is the difference between NonFataland Exceptionin Scala? Does Exceptionin Scala include fatal exception?

我想知道ScalaNonFatalExceptionScala 中有什么区别?ExceptionScala 中是否包含致命异常?

AFAIK in java, Exceptionis for non-fatal error and Erroris for fatal error. Is scala different with java in term of Exception?

java中的AFAIK,Exception用于非致命错误,Error用于致命错误。scala 与 java 在Exception什么方面不同?

Which way is the correct one to catch non-fatal exception?

哪种方法是捕获非致命异常的正确方法?

回答by Vladimir Matveev

Edit:updated for the latest Scala version (2.11+ has a different definition of NonFatal.apply).

编辑:针对最新的 Scala 版本进行了更新(2.11+ 对 的定义有所不同NonFatal.apply)。



NonFatalis just a convenient extractor which is defined in scala.util.control:

NonFatal只是一个方便的提取器,定义在scala.util.control

object NonFatal {
   /**
    * Returns true if the provided `Throwable` is to be considered non-fatal, or false if it is to be considered fatal
    */
   def apply(t: Throwable): Boolean = t match {
     // VirtualMachineError includes OutOfMemoryError and other fatal errors
     case _: VirtualMachineError | _: ThreadDeath | _: InterruptedException | _: LinkageError | _: ControlThrowable => false
     case _ => true
   }
  /**
   * Returns Some(t) if NonFatal(t) == true, otherwise None
   */
  def unapply(t: Throwable): Option[Throwable] = if (apply(t)) Some(t) else None
}

There is no special "fatal" kind of exceptions on JVM - Errors are not always "fatal", they're just a special kind of internal exceptions. "Fatal" exceptions are just a list of exceptions used in NonFataldefinition. In this terminology all Exceptions except InterruptedExceptionare considered non-fatal. It makes sense to consider InterruptedExceptionfatal because it means that the thread is interrupted, so if you want to handle it you should do it explicitly.

JVM 上没有特殊的“致命”异常——sError并不总是“致命”,它们只是一种特殊的内部异常。“致命”异常只是NonFatal定义中使用的异常列表。在这个术语中,Exception除此之外的所有s 都InterruptedException被认为是非致命的。考虑InterruptedExceptionfatal是有道理的,因为这意味着线程被中断了,所以如果你想处理它,你应该明确地去做。

NonFatalextractor also handles ControlThrowables correctly. These are exceptions which are thrown by special control transfer functions like breakinside breakable.

NonFatal提取器也可以ControlThrowable正确处理s。这些是由特殊控制传递函数(如breakinside )抛出的异常breakable

回答by OBarros

Exceptions don't get mentioned very much in Scala, but they're still what is done multiple times when dealing with unexpected failure.

在 Scala 中很少提到异常,但在处理意外失败时,它们仍然是多次完成的事情。

When we look for When to catch java.lang.Error?multiple answers, and opinions will be present, but let's focus on the common part.

当我们寻找何时捕捉java.lang.Error?多个答案,都会有意见,但让我们关注共同点。

A reasonable application should not try to catch

一个合理的应用程序不应该试图抓住

  • "An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch."
  • "Thrown to indicate that the Java Virtual Machine is broken or has run out of resources necessary for it to continue operating."
  • "Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector."
  • “一个错误是 Throwable 的一个子类,它表明一个合理的应用程序不应该试图捕捉的严重问题。”
  • “抛出表示 Java 虚拟机已损坏或已用完其继续运行所需的资源。”
  • “当 Java 虚拟机由于内存不足而无法分配对象时抛出,垃圾收集器无法提供更多内存。”

NonFatalis an Extractor of non-fatal Throwables. Will not match fatal errors like VirtualMachineError(for example, OutOfMemoryErrorand StackOverflowError, subclasses of VirtualMachineError), ThreadDeath, LinkageError, InterruptedException, ControlThrowable, that are part of the failures a reasonable application should'nt try to catch.

NonFatal是非致命 Throwables 的提取器。将不匹配一样致命错误VirtualMachineError(例如,OutOfMemoryErrorStackOverflowError,的子类VirtualMachineError), ,ThreadDeathLinkageErrorInterruptedExceptionControlThrowable是失败合理应用should'nt试图抓住的一部分。

With this in mind, we could write code that catches all harmless Throwables can be caught by:

考虑到这一点,我们可以编写代码来捕获所有可以通过以下方式捕获的无害 Throwables:

try {
  // dangerous code
} catch {
  case NonFatal(e) => log.error(e, "Something not that bad.")
}

If we look at the apply method we can see it very clearly.

如果我们查看 apply 方法,我们可以非常清楚地看到它。

object NonFatal {
   /**
    * Returns true if the provided `Throwable` is to be considered non-fatal, or false if it is to be considered fatal
    */
   def apply(t: Throwable): Boolean = t match {
     // VirtualMachineError includes OutOfMemoryError and other fatal errors
     case _: VirtualMachineError | _: ThreadDeath | _: InterruptedException | _: LinkageError | _: ControlThrowable => false
     case _ => true
   }
}