Exceptions don't get mentioned very much in Scala, but they're still what is done multiple times when dealing with unexpected failure.
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.
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."
NonFatal
is an Extractor of non-fatal Throwables. Will not match fatal errors like VirtualMachineError
(for example, OutOfMemoryError
and StackOverflowError
, subclasses of VirtualMachineError
), ThreadDeath
, LinkageError
, InterruptedException
, ControlThrowable
, that are part of the failures a reasonable application should'nt try to catch.
With this in mind, we could write code that catches all harmless Throwables can be caught by:
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.
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
}
}