sanctuary-def icon indicating copy to clipboard operation
sanctuary-def copied to clipboard

Expose exception types for verification of real time data in application code.

Open JAForbes opened this issue 8 years ago • 5 comments

This is just a vague musing. I'd really like to hear some differing points of view.

Would anyone else find it useful to have more control over how sanctuary responds to type errors?

Here are some scenario's I'm imagining:

Decorating an existing API with def and defining RecordType's for valid request/responses and then intercepting type errors to provide a user facing API Error e.g. a required property, or an invalid property type.

It'd would also be helpful for unit testing libraries that sit on top of sanctuary-def. Currently I do some string searching of error messages in sum-type, in order to verify a particular error is thrown. It would be a lot more precise if the various exceptions were documented and exposed and considered part of the API surface (e.g. semver).

Maybe sanctuary-def could allow rejection behaviour to be specified by the user. E.g. on error, you could write the particular error to an error stream. Maybe if there was a low level def that allowed you to pass in a resolve/reject function. The default def would throw. But we could optionally create def functions that reject via an Either, a Task or a Future in the event a Type error occurs.

It'd also be great if sanctuary-def could expose as much information as possible about the type error on the Error object. If a property was missing on a Record type, which ones? If there was an unexpected value, what was it?

This may be well beyond the scope of the library. I'd really love to hear criticisms, or any other related ideas.

JAForbes avatar Mar 15 '17 07:03 JAForbes

I see a lot of value in providing ways to reuse the library's validation logic.

Have you played with the validate method at all? It may satisfy some of your requirements:

> $.RecordType({x: $.FiniteNumber, y: $.FiniteNumber}).validate({x: 0, y: Infinity})
Left({propPath: ['y'], value: Infinity})

davidchambers avatar Mar 15 '17 12:03 davidchambers

@davidchambers I hadn't seen that before. Thanks!

JAForbes avatar Mar 15 '17 12:03 JAForbes

@davidchambers is it possible to evaluate the error message without first creating a function via def, and then applying it with the wrong arguments.

I've just started using sanctuary-def in some unit tests to verify data matches a schema, but I'm not sure how to render the output of validate as something useful for a test failure message.

JAForbes avatar Apr 28 '17 11:04 JAForbes

This is somewhat related to #135.

Could you provide an example, @JAForbes, of what you'd like to present to your users? The sanctuary-def error message verbatim?

davidchambers avatar Apr 28 '17 12:04 davidchambers

I think there's a few different use cases. For generating error messages for users of libraries built on to of sanctuary-def, I think validate's behaviour is probably adequate. For usage in unit tests, it'd be nice to have a built in like:

> var assertType = (T, a) => def('assertType', {}, [$.Type, T], i => i )(T, a)
undefined
> assertType( $.Number, '4' )

TypeError: Invalid value

assertType :: Type -> Number
                      ^^^^^^
                        1

1)  "4" :: String

The value at position 1 is not a member of ‘Number’.

I mean that signature or error message isn't really accurate, I want it to say, the second argument should be a member of the type provided as the first argument.

In any case, that particular error message would be more useful than validates output when asserting a value is of a particular type.

But if you have suggestions for a better error message I'd love to hear it.

JAForbes avatar Apr 30 '17 06:04 JAForbes