After I had used throw and catch throughout my whole typescript/node application at first, I stumbled over neverthrow(https://www.npmjs.com/package/neverthrow).
It took me to write my first, larger application and typescript, to realize what a big issue the missing ability to mark a function as throwing actually is.
neverthrow or other either based solutions seem just fine. For my non-Async functions I have already changed everything to neverthrow.
I don't really see the point, why I should bother to wrap all my async functions to return ResultAsync though. Any async function is marked as possibly throwing an error by nature(as they return a Promise), or am I wrong? Is there any point I missing and I should indeed change all async functions to use ResultAsync?
CodePudding user response:
There's few benefits to using something like the ResultAsync<T, E>
type instead of a Promise<T>
.
As can be seen from the type itself, the former option has a E
generic parameter indicating the types of errors that the result may contain. This is hugely beneficial, as you can deal with each error type independently instead of catching a generic error instance. Take for example HTMLImageElement.decode; it returns a promise that might throw EncodingError
, but you wouldn't know that without checking documentation.
Another benefit comes from being forced to deal with the potential error result. Javascript errors are unchecked, meaning that there is no compiler or interpreter to ensure that you always wrap await promise
in a try-catch. On the other hand, when you await result
, you must check whether it yielded a result (result.isOk() === true
) or threw an error (result.isErr() === true
). This means that every time you want to unwrap (get T
from Result<T, _>
) a result, you must deal with the potential error cases. In theory, this results in more robust and fail-safe code.
Result does not come without its downsides though. Javascript ecosystem has adopted Promises as the standard way to return things asynchronously, so ResultAsync
may not work everywhere Promise
would. Also, having to deal with potential error results every time you want to unwrap a result makes code more verbose.
If you're mostly dealing with async code written within the same project and think you could benefit from more fail-safe code, it may make sense to use ResultAsync
everywhere you'd use Promise
.