wellcrafted
Version:
Delightful TypeScript patterns for elegant, type-safe applications
106 lines (104 loc) • 3.36 kB
JavaScript
import { Err } from "../result-BJtW-Wuc.js";
//#region src/error/utils.ts
/**
* Extracts a readable error message from an unknown error value
*
* This utility is commonly used in mapErr functions when converting
* unknown errors to typed error objects in the Result system.
*
* @param error - The unknown error to extract a message from
* @returns A string representation of the error
*
* @example
* ```ts
* // With native Error
* const error = new Error("Something went wrong");
* const message = extractErrorMessage(error); // "Something went wrong"
*
* // With string error
* const stringError = "String error";
* const message2 = extractErrorMessage(stringError); // "String error"
*
* // With object error
* const unknownError = { code: 500, details: "Server error" };
* const message3 = extractErrorMessage(unknownError); // '{"code":500,"details":"Server error"}'
*
* // Used in mapErr function
* const result = await tryAsync({
* try: () => riskyOperation(),
* mapErr: (error) => Err({
* name: "NetworkError",
* message: extractErrorMessage(error),
* context: { operation: "riskyOperation" },
* cause: error,
* }),
* });
* ```
*/
function extractErrorMessage(error) {
if (error instanceof Error) return error.message;
if (typeof error === "string") return error;
if (typeof error === "object" && error !== null) {
const errorObj = error;
if (typeof errorObj.message === "string") return errorObj.message;
if (typeof errorObj.error === "string") return errorObj.error;
if (typeof errorObj.description === "string") return errorObj.description;
try {
return JSON.stringify(error);
} catch {
return String(error);
}
}
return String(error);
}
/**
* Returns two different factory functions for tagged errors.
*
* Given an error name like "NetworkError", this returns:
* - `NetworkError`: Creates a plain TaggedError object
* - `NetworkErr`: Creates a TaggedError object wrapped in an Err result
*
* The naming pattern automatically replaces the "Error" suffix with "Err" suffix
* for the Result-wrapped version.
*
* @param name - The name of the error type (must end with "Error")
* @returns An object with two factory functions:
* - [name]: Function that creates plain TaggedError objects
* - [name with "Error" replaced by "Err"]: Function that creates Err-wrapped TaggedError objects
*
* @example
* ```ts
* const { NetworkError, NetworkErr } = createTaggedError('NetworkError');
*
* // NetworkError: Creates just the error object
* const error = NetworkError({
* message: 'Connection failed',
* context: { url: 'https://api.example.com' },
* cause: undefined
* });
* // Returns: { name: 'NetworkError', message: 'Connection failed', ... }
*
* // NetworkErr: Creates error and wraps in Err result
* return NetworkErr({
* message: 'Connection failed',
* context: { url: 'https://api.example.com' },
* cause: undefined
* });
* // Returns: Err({ name: 'NetworkError', message: 'Connection failed', ... })
* ```
*/
function createTaggedError(name) {
const errorConstructor = (error) => ({
...error,
name
});
const errName = name.replace(/Error$/, "Err");
const errConstructor = (error) => Err(errorConstructor(error));
return {
[name]: errorConstructor,
[errName]: errConstructor
};
}
//#endregion
export { createTaggedError, extractErrorMessage };
//# sourceMappingURL=index.js.map