Class NonFatal
Throwable as
non-fatal — safe to capture, map, and recover from as an ordinary failure
value — or fatal, signaling a condition that should propagate rather than
travel through a pipeline.
The fatal set is:
VirtualMachineError— e.g.OutOfMemoryError,StackOverflowError: the JVM itself is compromised.LinkageError— the class environment is broken.InterruptedException— cancellation, not failure: swallowing it defeats cooperative shutdown.
Error subclasses such as
AssertionError — is considered non-fatal. This follows the spirit of Scala's
scala.util.control.NonFatal, whose fatal set additionally includes
ThreadDeath and ControlThrowable — the former is deprecated for
removal and no longer thrown by the JVM, and the latter has no Java analogue.
CancellationException is deliberately non-fatal,
even though it also signals cancellation: it is the library's own convention to
surface a cancelled future as an ordinary failure value
(Try.fromFuture
manufactures exactly that), and unlike InterruptedException it carries no
thread-local interrupt flag that swallowing would lose.
check(Throwable) classifies only the given throwable. Borders that need
chain-aware handling (interruption in particular often arrives wrapped as another
exception's cause) should use rethrowIfFatal(Throwable) or
Try.rethrowFatal().
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionstatic booleanReturnstrueifthrowableis non-fatal.static voidrethrowIfFatal(Throwable throwable) Rethrowsthrowableif it — or any throwable reachable through its cause chain and suppressed exceptions — is fatal percheck(Throwable); otherwise returns normally.
-
Method Details
-
check
Returnstrueifthrowableis non-fatal.- Parameters:
throwable- the throwable to classify; must not benull- Returns:
trueif non-fatal,falseif fatal- Throws:
NullPointerException- ifthrowableisnull
-
rethrowIfFatal
Rethrowsthrowableif it — or any throwable reachable through its cause chain and suppressed exceptions — is fatal percheck(Throwable); otherwise returns normally.If an
InterruptedExceptionis reachable, the current thread's interrupt flag is set before anything is thrown — note this propagates the interruption to the calling thread, which is not necessarily the thread the exception was raised on. A fatalErrortakes priority and is rethrown as-is. Otherwise an interruption is rethrown unchecked: asthrowableitself when it already is aCompletionException(not wrapped again), and asnew CompletionException(throwable)otherwise — the full original graph stays reachable through the cause.CompletionExceptionis also the transport wrapper the library's future borders deliberately strip (Try.fromFutureand friends), so a rethrown interruption that crosses a future boundary comes back as an ordinaryFailure— with theInterruptedExceptionintact as its cause. The rethrow therefore guards a synchronous border only: after a future round-trip, applyTry.rethrowFatal()again on the receiving side and the interruption is re-detected.Traversal is bounded at 1000 throwables — a backstop against hostile
getCause()overrides — so a fatal parked beyond that bound goes undetected. Cause cycles are detected without allocation (Floyd's algorithm) and abandoned, so a cycle neither loops nor starves the rest of the graph. The dominant shapes — a plain cause chain, or one level of suppressed exceptions as parked byResource— are traversed without building auxiliary structures (thoughgetSuppressed()itself clones its array when non-empty); a worklist is built only when a suppressed throwable carries a graph of its own.- Parameters:
throwable- the throwable to inspect; must not benull- Throws:
NullPointerException- ifthrowableisnullError- if a fatalErroris reachable within the traversal boundCompletionException- if anInterruptedExceptionis reachable and no fatalErroris present
-