/** * An Error base-class that also provides some additional context. * * All first-party error handlers in Extollo can render the context as part of * the display of the error (e.g. in the console, in the HTML response, &c.) * * @example * ```typescript * function myFunc(arg1, arg2) { * // ...do something... * throw new ErrorWithContext('Something went wrong!', { arg1, arg2 }) * } * ``` */ export class ErrorWithContext extends Error { public context: {[key: string]: any} = {} public originalError?: Error constructor( message: string, context?: {[key: string]: any}, ) { super(message) if ( context ) { this.context = context } } } export function withErrorContext(closure: () => T, context: {[key: string]: any}): T { try { return closure() } catch (e: unknown) { if ( e instanceof ErrorWithContext ) { e.context = { ...e.context, ...context, } throw e } else if ( e instanceof Error ) { const ewc = new ErrorWithContext(e.message, context) ewc.stack = e.stack ewc.name = e.name ewc.originalError = e throw ewc } else { throw e } } }