In my view returning an error in a fulfilled promise is at best incongruous, at worst a violation of the semantics of a promise … because the recipient of that promise has to be prepared to handle an error in a
then handler, something that really is the responsibility of a
Both promises and
Js.Result.t allow Railway Oriented Programming but they do so in very different ways. With
Js.Result.t the value can simply be extracted with pattern matching because the value is known to exist - due to the asynchronous nature of a promise, the contained value has to be manipulated via a handler. A rule of thumb for the promise/handler chains seems to be:
then handler processes a value in a fulfilled promise - typically assumed to be a successful result
catch handler processes a value in a rejected promise - typically assumed to be a failure result
regardless of whether that promise/handler chain is scaffolded and terminated in one single place or composed in a more distributed fashion throughout the code base. So the
then handlers compose the “green” track, while the
catch handlers compose the “red” track of the “Railway Oriented” promise/handler pipeline.
It’s an implementation detail that ultimately a promise has to be resolved by the time the promise/handler chain terminates in order to avoid an
If it is convenient/necessary to convert a rejected promise to a
Js.Result.t then it makes sense for a
catch handler to wrap the error result and forward the
Error to where it can be adequately processed.
catch handler is known to be the final, terminating
catch handler of the chain then it makes sense to resolve to an empty value consistent with the type of the promise in order to prevent an
If however the promise itself is returned or passed on then the
catch handler should create another rejected promise adhering to the standard promise protocol of indicating the condition of failure.
As far as I can tell
Js.Promise.reject does not adhere to the convention of the host construct as it requires an
exn rather than a
For debugging purposes and selective error catching, it is useful to make
catch handler is to use
Js.Exn.raiseError and the like.
For these reasons I feel that fulfilled promises holding error results are a somewhat dubious practice as they seem to run counter to the whole concept of “fulfilled” and “rejected” promises.