import { assertMethodDecorator } from "../common/decorators.js"; import type { Method } from "../common/types.js"; import { isPromise, resolveCallable, } from "../common/utils.js"; export interface OnErrorConfig { func: OnErrorHandler | keyof This; } export type OnErrorHandler = (error: any, args: Args) => Return | Promise>; export function createOnErrorMethod( originalMethod: Method, config: OnErrorConfig, ): Method { return function(this: This, ...args: Args): Return { const onErrorFunc = resolveCallable>>(this, config.func); try { const result = originalMethod.apply(this, args); if (isPromise(result)) { return result.catch((error) => { return onErrorFunc(error, args); }) as Return; } return result; } catch (error) { return onErrorFunc(error, args) as Return; } }; } export function onError( config: OnErrorConfig, ) { return function( value: Method, context: ClassMethodDecoratorContext>, ): Method { assertMethodDecorator("onError", value, context); return createOnErrorMethod(value, config); }; }