UNPKG

@shirudo/base-error

Version:

A simple error base class for TypeScript

105 lines (102 loc) 4.2 kB
/** * Application-specific base error that works across full Node.js, isolate "edge" * runtimes (Cloudflare Workers, Deno Deploy, Vercel Edge Functions) and modern * browsers. It preserves the native `cause` field where available, falls back * gracefully where it is not, and produces the richest stack trace the host * can provide. * * This class includes support for default and localized user-friendly messages. * * @example * ```ts * // Using automatic name inference * class UserNotFoundError extends BaseError<'UserNotFoundError'> { * constructor(userId: string) { * super(`User with id ${userId} not found in database lookup`); // Technical message * this.withUserMessage(`User ${userId} was not found.`); // User-friendly message * } * } * ``` */ declare class BaseError<T extends string> extends Error { #private; readonly name: T; /** Epoch-ms timestamp (numeric) */ readonly timestamp: number; /** ISO-8601 timestamp (string) for log aggregators that prefer text */ readonly timestampIso: string; /** Rich, filtered stack where the host supports it. */ readonly stack?: string; private _defaultUserMessage?; private _localizedMessages; /** * Creates a new BaseError instance with automatic name inference. * * @param message – Human-readable explanation (name will be inferred from constructor) * @param cause – Optional underlying error or extra context */ constructor(message: string, cause?: unknown); /** * Sets the default user-friendly message. * This is used as a fallback when a specific localization is not available. * @param message The default user-friendly message (typically in English). * @returns The error instance for chaining. */ withUserMessage(message: string): this; /** * Adds a user-friendly message for a specific language. * Throws an error if a message for the given language already exists. * @param lang The language code (e.g., 'de', 'es', 'fr-CA'). * @param message The localized message. * @returns The error instance for chaining. * @throws Error if a message for the given language already exists. */ addLocalizedMessage(lang: string, message: string): this; /** * Updates or sets a user-friendly message for a specific language. * This method allows overwriting existing messages for the same language. * @param lang The language code (e.g., 'de', 'es', 'fr-CA'). * @param message The localized message. * @returns The error instance for chaining. */ updateLocalizedMessage(lang: string, message: string): this; /** * Retrieves the most appropriate user-friendly message based on language preference. * The fallback order is: preferred language -> fallback language -> default message. * @param options - Language preference options. * @returns The user-friendly message, or `undefined` if none is set. */ getUserMessage(options?: { preferredLang?: string; fallbackLang?: string; }): string | undefined; /** Serialises the error for JSON logs */ toJSON(): Record<string, unknown>; /** Readable one-liner plus optional nested cause. */ toString(): string; } /** * Asserts that a condition is truthy, throwing the provided error if it's falsy. * This function provides TypeScript type narrowing through assertion signatures. * * @template T - The error name type extending string * @param condition - The value to check for truthiness * @param error - The BaseError instance to throw if condition is falsy * @throws {BaseError<T>} The provided error when condition is falsy * * @example * ```ts * const user = getUser(); * guard(user, new UserNotFoundError("User not found")); * // TypeScript now knows user is not null/undefined * console.log(user.name); * ``` * * @example * ```ts * guard(isValidEmail(email), new ValidationError("Invalid email format")); * // Continues execution only if email is valid * ``` */ declare function guard<T extends string>(condition: unknown, error: BaseError<T>): asserts condition; export { BaseError, guard };