From 58a9c5d814d9c1711c4584db0ec68fb21b1d7ae0 Mon Sep 17 00:00:00 2001 From: Paul J Thordarson Date: Fri, 31 Jan 2025 08:27:41 -0500 Subject: [PATCH] Create UnsafeNonFatal for use in the fiber runtime --- .../cats/effect/unsafe/UnsafeNonFatal.scala | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 core/shared/src/main/scala/cats/effect/unsafe/UnsafeNonFatal.scala diff --git a/core/shared/src/main/scala/cats/effect/unsafe/UnsafeNonFatal.scala b/core/shared/src/main/scala/cats/effect/unsafe/UnsafeNonFatal.scala new file mode 100644 index 0000000000..af7e365a2c --- /dev/null +++ b/core/shared/src/main/scala/cats/effect/unsafe/UnsafeNonFatal.scala @@ -0,0 +1,45 @@ +/* + * Copyright 2020-2025 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cats.effect +package unsafe + +import scala.util.control.ControlThrowable + +/** + * An alternative to [[scala.util.control.NonFatal]] that does not treat + * [[java.lang.InterruptedException]] as fatal. This is intended for the exclusive use of the + * Cats-Effect runtime. It is not recommended to treat interrupts as non-fatal in application + * code, as handling interrupts gracefully is the responsibility of the runtime, so + * [[UnsafeNonFatal]] should only be used in the fiber runtime. + */ +object UnsafeNonFatal { + + /** + * 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 _: VirtualMachineError | _: ThreadDeath | _: LinkageError | _: ControlThrowable => + false + case _ => true + } + + /** + * Returns Some(t) if RuntimeNonFatal(t) == true, otherwise None + */ + def unapply(t: Throwable): Option[Throwable] = Some(t).filter(apply) +}