Scala 中 NonFatal 和 Exception 的区别
The difference between NonFatal and Exception in Scala
在this article中说:
If you want to catch “everything” that would normally happen, then use
NonFatal:
import scala.util.control.NonFatal
try {
operation()
} catch {
case NonFatal(e) => errorHandler(e)
}
不过我一般用Exception
:
try {
operation()
} catch {
case e: Exception => errorHandler(e)
}
我想知道 Scala 中 NonFatal
和 Exception
有什么区别? Scala 中的 Exception
是否包含致命异常?
AFAIK in java,Exception
用于非致命错误,Error
用于致命错误。 Scala 在 Exception
方面与 java 不同吗?
捕获非致命异常的正确方法是什么?
编辑: 更新为最新的 Scala 版本(2.11+ 对 NonFatal.apply
有不同的定义)。
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
}
JVM 上没有特殊的 "fatal" 种异常 - Error
并不总是 "fatal",它们只是一种特殊的内部异常。 "Fatal" 异常只是 NonFatal
定义中使用的异常列表。在这个术语中,除了 InterruptedException
之外的所有 Exception
都被认为是非致命的。考虑 InterruptedException
fatal 是有意义的,因为这意味着线程被中断,所以如果你想处理它,你应该显式地处理它。
NonFatal
提取器也能正确处理 ControlThrowable
s。这些是由特殊控制传递函数抛出的异常,例如 breakable
.
中的 break
Scala 中很少提及异常,但在处理意外故障时仍然会多次执行异常。
当我们寻找什么时候抓住java.lang.Error?多个答案,意见会出现,但让我们集中精力在公用部分。
一个合理的应用应该不会尝试去捕获
- "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."
NonFatal
是非致命 Throwable 的提取器。不会匹配 VirtualMachineError
(例如,OutOfMemoryError
和 WhosebugError
,VirtualMachineError
的子类)、ThreadDeath
、LinkageError
、InterruptedException
、ControlThrowable
,这是合理的应用程序不应尝试捕获的故障的一部分。
考虑到这一点,我们可以编写代码来捕获所有无害的 Throwable 可以通过以下方式捕获:
try {
// dangerous code
} catch {
case NonFatal(e) => log.error(e, "Something not that bad.")
}
如果我们看一下 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
}
}
在this article中说:
If you want to catch “everything” that would normally happen, then use NonFatal:
import scala.util.control.NonFatal
try {
operation()
} catch {
case NonFatal(e) => errorHandler(e)
}
不过我一般用Exception
:
try {
operation()
} catch {
case e: Exception => errorHandler(e)
}
我想知道 Scala 中 NonFatal
和 Exception
有什么区别? Scala 中的 Exception
是否包含致命异常?
AFAIK in java,Exception
用于非致命错误,Error
用于致命错误。 Scala 在 Exception
方面与 java 不同吗?
捕获非致命异常的正确方法是什么?
编辑: 更新为最新的 Scala 版本(2.11+ 对 NonFatal.apply
有不同的定义)。
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
}
JVM 上没有特殊的 "fatal" 种异常 - Error
并不总是 "fatal",它们只是一种特殊的内部异常。 "Fatal" 异常只是 NonFatal
定义中使用的异常列表。在这个术语中,除了 InterruptedException
之外的所有 Exception
都被认为是非致命的。考虑 InterruptedException
fatal 是有意义的,因为这意味着线程被中断,所以如果你想处理它,你应该显式地处理它。
NonFatal
提取器也能正确处理 ControlThrowable
s。这些是由特殊控制传递函数抛出的异常,例如 breakable
.
break
Scala 中很少提及异常,但在处理意外故障时仍然会多次执行异常。
当我们寻找什么时候抓住java.lang.Error?多个答案,意见会出现,但让我们集中精力在公用部分。
一个合理的应用应该不会尝试去捕获
- "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."
NonFatal
是非致命 Throwable 的提取器。不会匹配 VirtualMachineError
(例如,OutOfMemoryError
和 WhosebugError
,VirtualMachineError
的子类)、ThreadDeath
、LinkageError
、InterruptedException
、ControlThrowable
,这是合理的应用程序不应尝试捕获的故障的一部分。
考虑到这一点,我们可以编写代码来捕获所有无害的 Throwable 可以通过以下方式捕获:
try {
// dangerous code
} catch {
case NonFatal(e) => log.error(e, "Something not that bad.")
}
如果我们看一下 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
}
}