Edit: updated for the latest Scala version (2.11+ has a different definition of NonFatal.apply
).
NonFatal
is just a convenient extractor which is defined in 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 – Error
s are not always “fatal”, they’re just a special kind of internal exceptions. “Fatal” exceptions are just a list of exceptions used in NonFatal
definition. In this terminology all Exception
s except InterruptedException
are considered non-fatal. It makes sense to consider InterruptedException
fatal because it means that the thread is interrupted, so if you want to handle it you should do it explicitly.
NonFatal
extractor also handles ControlThrowable
s correctly. These are exceptions which are thrown by special control transfer functions like break
inside breakable
.