The difference between NonFatal and Exception in Scala

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 – Errors 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 Exceptions 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 ControlThrowables correctly. These are exceptions which are thrown by special control transfer functions like break inside breakable.

Leave a Comment