@superbuilders/errors
Version:
Type-safe error handling library with error chaining, wrapping, and utilities inspired by Go
69 lines • 3.47 kB
TypeScript
type Success<T> = {
data: T;
error: undefined;
};
type Failure<E extends Error> = {
data: undefined;
error: E;
};
type Result<T, E extends Error = Error> = Success<T> | Failure<E>;
/**
* Represents an error that wraps another error, establishing a cause chain.
* @template C The type of the direct cause of this error.
*/
export interface WrappedError<C extends Error> extends Error {
readonly cause: C;
}
/**
* Recursively unwraps `WrappedError` types to find the type of the ultimate underlying cause.
* If the error is not a `WrappedError` or the chain ends, it returns the type of that error.
*
* @example
* type T0 = DeepestCause<WrappedError<Error>>; // Error
* type T1 = DeepestCause<WrappedError<TypeError>>; // TypeError
* type T2 = DeepestCause<WrappedError<WrappedError<SyntaxError>>>; // SyntaxError
* type T3 = DeepestCause<RangeError>; // RangeError
*/
export type DeepestCause<E extends Error> = E extends WrappedError<infer NextCause> ? DeepestCause<NextCause> : E;
declare function newError(message: string): Readonly<Error>;
declare function wrap<E extends Error>(originalError: E, message: string): Readonly<WrappedError<E>>;
/**
* Returns the underlying cause of the error.
* It traverses the error chain by accessing the `cause` property of each error,
* returning the first error in the chain that does not have a further `cause`
* that is an `Error` instance, or the error itself if it has no cause.
*
* If `error` is a `WrappedError<T>`, the return type will be the `DeepestCause<T>`,
* providing a precise type for the root cause.
* For other error types, it returns `Error`.
*/
declare function cause<T extends Error>(error: WrappedError<T>): DeepestCause<T>;
declare function cause<T extends Error>(error: T): Error;
/**
* Reports whether any error in err's chain matches target.
* The chain consists of err itself followed by the sequence of errors
* obtained by repeatedly accessing the `cause` property.
* An error is considered a match if it is identical (===) to target.
*/
declare function isError<T extends Error>(err: WrappedError<T>, target: T): boolean;
declare function isError<T extends Error, U extends Error>(err: WrappedError<T>, target: U): boolean;
declare function isError<T extends Error, U extends Error>(err: T, target: U): boolean;
/**
* Returns the first error in err's chain that matches `ErrorClass`.
* The chain consists of err itself followed by the sequence of errors
* obtained by repeatedly accessing the `cause` property.
*/
declare function asError<T extends Error, U extends Error>(err: WrappedError<T>, ErrorClass: new (...args: any[]) => U): U | undefined;
declare function asError<T extends Error, U extends Error>(err: T, ErrorClass: new (...args: any[]) => U): U | undefined;
/**
* Wraps a Promise to return a Result object, discriminating between success (data) and failure (error).
* If the promise rejects, the caught error is cast to type E.
*/
declare function tryCatch<T, E extends Error = Error>(promise: Promise<T>): Promise<Result<T, E>>;
/**
* Wraps a synchronous function to return a Result object, discriminating between success (data) and failure (error).
* If the function throws, the caught error is cast to type E.
*/
declare function trySync<T, E extends Error = Error>(fn: () => T): Result<T, E>;
export { newError as new, tryCatch as try, trySync, wrap, cause, isError as is, asError as as };
//# sourceMappingURL=index.d.ts.map