mapError
mapError
is used to transform an error of aResult
orAsyncResult
into a nextResult
orAsyncResult
.
This is especially useful when you want to transform the error into a different error type, or when you want to provide more context to the error:
declare function findUserById(id: number): AsyncResult<User, NotFoundError>;
const result = findUserById(1)
.mapError(() =>
new NotAllowedError("You are not allowed to perform this action.")
);
In the example above mapError
is used to transform the NotFoundError
into a NotAllowedError
, which makes more sense in the context of checking user permissions.
INFO
Be careful: mapError
will override any previous error that was captured in the chain.
Sometimes this may be exactly what you want, e.g. when bundling multiple errors into a single error type:
declare result: Result<string, FileNotExistsError | FilePermissionError>;
const nextResult = result.mapError((error) =>
new IOError("An error occurred while processing the file.", { cause: error })
);
In other cases, you may want to target a specific error or case. There are two ways to handle this:
Conditionally checking for errors
declare result: Result<string, ErrorA | ErrorB>;
const nextResult = result.mapError((error) => {
if (error.type === "error-a") {
return new ErrorC();
}
return error;
}) // Result<string, ErrorB | ErrorC>;
Nesting
declare result: Result<string, ErrorA>;
declare otherResult: Result<string, ErrorB>;
const nextResult = result.map(value =>
otherResult.mapError(() => new ErrorC()) // Result<string, ErrorC>
) // Result<string, ErrorA | ErrorC>;
The benefit of the latter approach is that the transformation is happening close to the source of the error, which can make the code more readable and maintainable.