zio-prelude
zio-prelude copied to clipboard
Catch Exceptions In Newtype Constructors
The following snippet will currently throw a runtime exception since the string cannot be parsed to a UUID
:
import java.util.UUID
type Id = Id.Type
object Id extends Newtype[UUID]
Id.make(UUID.fromString("foo"))
Instead, the implementation of make
could catch the error and render it as a string.
It is a little debatable whether we should catch thrown exceptions like this in addition to assertion failures but I tend to think with these "smart" types we should catch and render thrown exceptions, which I believe is similar to what would occur if an exception was thrown in assertTrue
.
Thanks to @wi101 for reporting.
Copying @kitlangton.
Currently, the type of make
is
def make(value: A): Validation[String, Type]
So we would need to change it to
def make(value: => A): Validation[String, Type]
right?
Since we're already changing the signature, why not even
def make(value: => A): Validation[IllegalArgumentException, Type]
to have richer information about the error?
I'm not sure if we need to do the by name parameter since we are doing this at compile time but we potentially could. I'm not sure we get that much value from making it an IllegalArgumentException
since if we do anything I think we would want to catch any errors that are not fatal so we would have to return Throwable
and at that point we aren't really getting any additional information.
I'm not sure if we need to do the by name parameter since we are doing this at compile time but we potentially could.
If we didn't do that, the type of the method would tell a different story from what effectively happens, right? I think that could unnecessarily confuse people.
I think evaluating something at compile time already kind of tells a different story but I don't think it is a problem to make it by name and looks like that is what we are doing with assertTrue
.