Are the `EitherAsync` methods `.map` and `.chain` deterministic
Are the EitherAsync methods .map and .chain deterministic, when the callback throws an error?
Having run the following code to test behaviour,
const e1 = await EitherAsync(() => Promise.resolve(true))
.map(async (b) => { throw new Error('Panic') }).run()
e1.isLeft() // true
e1.extract() // Error('Panic')
const e2 = await EitherAsync(() => Promise.resolve(true))
.chain(async (b) => { throw new Error('Panic') }).run()
e2.isLeft() // true
e2.extract() // Error('Panic')
it appears exceptions will be wrapped in a Left. This is desirable behaviour, but I can't see it in the docs.
If it is deterministic, I'm happy to open a PR to add examples to the docs.
On a related point, when the callbacks of the Either methods .map and .chain throw an error, they're not caught and transformed to a Left by purify-ts
Yes, this is desirable behaviour. It's not part of the docs, unfortunately, you are correct.
On a related point, when the callbacks of the Either methods .map and .chain throw an error, they're not caught and transformed to a Left by purify-ts
EitherAsync.map swallowing exceptions is 10% design choice and 90% just because EitherAsync is a wrapper on top of Promise so it's unavoidable. In an ideal world both methods would not catch errors.
Thanks for clarifying. Would you like me to a create a PR, to document the behaviour of EitherAsync when callbacks throw?
Or perhaps it's better to mandate in the docs that the user ensures callbacks don't throw?
I think both, users should know about this behaviour, but shouldn't abuse it.