An error type which is guaranteed to be useful.
In the Scala ecosystem, for better or worse, most errors end up getting converted to a subtype of
java.lang.Throwable, usually java.lang.RuntimeException. This is convenient, because it interoperates well
with the JVM ecosystem, but it has several notable drawbacks.
The primary draw back is that this valid instance of java.lang.RuntimeException,
scala> val e = new RuntimeException
val e = new RuntimeException
val e: RuntimeException = java.lang.RuntimeException
scala> e.getMessage
e.getMessage
val res0: String = null
scala> e.getCause
e.getCause
val res1: Throwable = null
One would be hard pressed to find a less helpful error. As amazing as it may seem, it is not uncommon to have
exceptions like this in real world production code.
Error is attempting to be the nicer version of java.lang.RuntimeException, which is compatible with all
existing error code and always gives you meaningful context about the error.
There are three common idioms in Scala code for handling errors.
Error aims to support all these cases.
It is an open trait
, so custom Error ADTs can extend it. This gives error handling code the ability to be generic
when needed, but still guarantees a reasonable error message.
Using the provided trivial implementation of Error, you can convert your ADT type into a Error when needed
or you can just create instances of Error directly and raise them, similar to `new RuntimeException().
Error also supports annotating Error#causes, similar to java.lang.Throwable#getCause, but more
expressive. Rather than having a single cause
(which may be null
) Error allows for an arbitrary number of
causes.
Finally, since Error extends java.lang.RuntimeException, it can dropped into place with any code currently
using java.lang.Throwable as the default bottom error type.