Подтвердить что ты не робот

Разница между NonFatal и Exception в Scala

В этой статье он сказал, что:

Если вы хотите поймать "все", что обычно происходит, используйте Нефатальный:

import scala.util.control.NonFatal

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

Но я обычно использую Exception:

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

Я хотел бы знать, в чем разница между NonFatal и Exception в Scala? Включает ли Exception в Scala фатальное исключение?

AFAIK в java, Exception предназначен для нефатальной ошибки, а Error - для фатальной ошибки. Является ли Scala отличным от java в терминах Exception?

Какой путь является правильным, чтобы поймать нефатальное исключение?

4b9b3361

Ответ 1

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 {
     case _: StackOverflowError => true // StackOverflowError ok even though it is a VirtualMachineError
     // VirtualMachineError includes OutOfMemoryError and other fatal errors
     case _: VirtualMachineError | _: ThreadDeath | _: InterruptedException | _: LinkageError | _: ControlThrowable | _: NotImplementedError => 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 нет особых "фатальных" исключений - Error не всегда "фатальны", это всего лишь особый вид внутренних исключений. Исключения "Fatal" - это всего лишь список исключений, используемых в определении NonFatal. В этой терминологии все Exception кроме InterruptedException считаются нефатальными. Имеет смысл считать InterruptedException фатальным, потому что это означает, что поток прерывается, поэтому, если вы хотите обработать его, вы должны сделать это явно.

NonFatal экстрактор также корректно обрабатывает ControlThrowable. Это исключения, которые генерируются специальными функциями передачи управления, такими как break внутри breakable.