Skip to content

Instantly share code, notes, and snippets.

@frgomes
Last active June 28, 2018 17:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save frgomes/89cc1ef2e816f49c4425 to your computer and use it in GitHub Desktop.
Save frgomes/89cc1ef2e816f49c4425 to your computer and use it in GitHub Desktop.
Scala - Handling Throwables safely
/**
* Safely handles ControlThrowable
*
* See: [[https://www.sumologic.com/2014/05/05/why-you-should-never-catch-throwable-in-scala/ Why you should never catch Throwable in Scala ]]
*
* See: [[https://github.com/scala/scala/blob/2.12.x/src/library/scala/util/control/NonFatal.scala scala.util.control.NonFatal.scala]
*/
trait CatchSafely {
import scala.util.control.ControlThrowable
def safely[T](handler: PartialFunction[Throwable, T]): PartialFunction[Throwable, T] = {
// if it is a condition which cannot be handled by application code...
case t: VirtualMachineError => throw t
case t: ThreadDeath => throw t
case t: InterruptedException => throw t
case t: LinkageError => throw t
case t: ControlThrowable => throw t
// if it's a Throwable the caller handles, pass it on to the caller...
case t: Throwable if handler.isDefinedAt(t) => handler(t)
// if it's a Throwable not handled by the caller, just rethrow.
case t: Throwable => throw t
}
}
object CatchSafely extends CatchSafely
@frgomes
Copy link
Author

frgomes commented Aug 7, 2015

Use case:

val either: Either[Throwable, Double] =
  try {
    Right(doSomeCalculationHere)
  } catch safely {
    case e: ArithmeticException => Right(0.0)
    case t: Throwable => Left(t)
  }

@frgomes
Copy link
Author

frgomes commented Aug 10, 2016

Another alternative, which is provided as part of Scala runtime library is NonFatal, as shown below:

val either: Either[Throwable, Double] =
  try {
    Right(doSomeCalculationHere)
  } catch {
    case NonFatal(t) =>
      if(t.isInstanceOf[ArithmeticException] Right(0.0) else Left(t)
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment