rescript-core
rescript-core copied to clipboard
Getting data out of an Error, easier classifying unknown values, "Type" module thoughts
I'm trying to do something simple. I caught a Firebase exception and want to access the code
property that is a string. Firebase errors have code properties with contents like "auth/email-password-invalid". How can I do that? Here is one awkward way. Is there a simpler way?
@get_index external getErrorProperty: (Error.t, string) => option<'a> = ""
let toString1 = i =>
switch i->Type.Classify.classify {
| String(s) => Some(s)
| _ => None
}
let printError = (err: Error.t) =>
err
->getErrorProperty("code")
->toString1
->Option.getWithDefault("No code found in the exception")
->Console.log
I think it would be useful to access arbitrary properties on Error.t
just like I can on Object.t
. I also want a much easier way to work with those values and not have to switch on Type.Classify.classify
.
First idea is to add an Error.get
function just like we have Object.get
. This would be very convenient.
Second idea is to add convenience methods for classify like this. All these do is wrap the classify function with a Switch.
let classify: 'a => classified
let toString: 'a => option<string>
let toFloat: 'a => option<float>
The third idea is to rename the Type
module to Unknown
and have an unknown
type. When we have functions that return some unknown thing we could label them explicitly as unknown
and the developer will then know they can use the Unknown
module to classify and make sense of it. The rescript-struct module defines as unknown
type that is used for serialization output. https://github.com/DZakh/rescript-struct#sserializewith TypeScript has an unknown
type. The Object.get
function returns an option<'a>
which is too permissive because you can Option.map it and start treating it like something it is not and get a runtime error. So Object.get
should return an option<unknown>
and force the developer to safely inspect and classify it.
Finally and some random thoughts on the Type
module.
- It won't classify a
bigint
. - The classify symbol doesn't result in a
Symbol.t
- it is aType.Classify.symbol
- The classification method uses
toString
. Why nottypeof
? Wouldn't that be more efficient? - For a tiny module it is kind of annoying having a
Classify
sub-module just to hold theclassify
function. Couldn't this all be flattened out?