UNPKG

@travetto/runtime

Version:

Runtime for travetto applications.

78 lines (69 loc) 2.26 kB
import { castTo } from './types.ts'; export type ErrorCategory = 'general' | 'notfound' | 'data' | 'permissions' | 'authentication' | 'timeout' | 'unavailable'; export type AppErrorOptions<T> = ErrorOptions & { at?: Date | string | number; type?: string; category?: ErrorCategory; } & (T extends undefined ? { details?: T } : { details: T }); /** * Framework error class, with the aim of being extensible */ export class AppError<T = Record<string, unknown> | undefined> extends Error { static defaultCategory?: ErrorCategory; /** Convert from JSON object */ static fromJSON(error: unknown): AppError | undefined { if (!!error && typeof error === 'object' && ('message' in error && typeof error.message === 'string') && ('category' in error && typeof error.category === 'string') && ('type' in error && typeof error.type === 'string') && ('at' in error && typeof error.at === 'string') ) { return new AppError(error.message, castTo<AppErrorOptions<Record<string, unknown>>>(error)); } } type: string; category: ErrorCategory; at: string; details: T; /** * Build an app error * * @param message The error message */ constructor( ...[message, options]: T extends undefined ? ([string] | [string, AppErrorOptions<T>]) : [string, AppErrorOptions<T>] ) { super(message, options?.cause ? { cause: options.cause } : undefined); this.type = options?.type ?? this.constructor.name; this.details = options?.details!; this.category = options?.category ?? castTo<typeof AppError>(this.constructor).defaultCategory ?? 'general'; this.at = new Date(options?.at ?? Date.now()).toISOString(); } /** * Serializes an error to a basic object */ toJSON(): AppErrorOptions<T> & { message: string } { const options: AppErrorOptions<unknown> = { category: this.category, ...(this.cause ? { cause: `${this.cause}` } : undefined), type: this.type, at: this.at, ...(this.details ? { details: this.details } : undefined!), }; // eslint-disable-next-line @typescript-eslint/consistent-type-assertions return { message: this.message, ...options as AppErrorOptions<T> }; } }