Open macksal opened 1 month ago
Latest commit: 69bb69745627a34684927bec13f19cbd702f56b2
The changes in this PR will be included in the next version bump.
Not sure what this means? Click here to learn what changesets are.
Click here if you're a maintainer who wants to add another changeset to this PR
@mattpocock @supermacro @m-shaka
This functionality has been discussed at a few points in the past, I really appreciate any comments on this implementation. Or if it simply isn't a priority for the library, please let me know! Eager to hear any feedback.
I'm ready to use this in my own applications, but I'd prefer to settle on a particular interface before doing that (instead of e.g. forking off).
This PR is related to the earlier #536 which proposed an implementation for an
andFinally
method that will be called regardless of whether an earlier step contained an error or not. This would allow the caller to avoid awkward constructs which pass the same or similar callback to bothmap
/mapErr
orandThen
/orElse
.The earlier implementation had some problems, and I believe the design still needed some considerations. Primarily, the earlier version did not allow for asynchronous cleanup logic which is a common use case for resources such as database connections, login sessions, etc.
The primary use case considered is one similar to the following. More broadly, the feature is designed to cover use cases that would be normally covered by the
finally
block in either synchronous or asynchronous code.Design decisions
This feature was designed explicitly to handle scenarios which would normally be covered by the
finally
block in code that synchronously throws errors or usesasync/await
. This allows similar thought patterns easily apply to this library, and such code to more easily be updated to useneverthrow
.Key decisions are outlined below with further context.
1. The andFinally callback does not receive a parameter.
2. ResultAsync.andFinally must return a Result/ResultAsync and `ok` values are ignored.
3. When andFinally returns an error, that error will propagate (and overwrite a previous error).
4. Result.andFinally can return only a synchronous Result and not a ResultAsync.
5. ResultAsync.andFinally will call the cleanup function even if the internal promise rejects