zio-prelude icon indicating copy to clipboard operation
zio-prelude copied to clipboard

Catch Exceptions In Newtype Constructors

Open adamgfraser opened this issue 2 years ago • 4 comments

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.

adamgfraser avatar Mar 04 '22 16:03 adamgfraser

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?

sideeffffect avatar Mar 06 '22 12:03 sideeffffect

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.

adamgfraser avatar Mar 06 '22 18:03 adamgfraser

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.

sideeffffect avatar Mar 06 '22 19:03 sideeffffect

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.

adamgfraser avatar Mar 07 '22 17:03 adamgfraser