// Modified from https://github.com/enkot/catch-decorator import { decorator_compatibility } from "./utils"; type HandlerFunction = (error: any, ctx: T) => void; type CatchDecorator = (object: T, key: string, desc: PropertyDescriptor) => PropertyDescriptor export interface CatchOptions { log: boolean; } interface IntCatchOptions extends CatchOptions { errorClass: any, handler: HandlerFunction } function handleError( ctx: T, error: any, options: IntCatchOptions ) { if (!options.errorClass || error instanceof options.errorClass) { Catch.invokeHandler(options.handler, error, ctx) if (options.log) Catch.logger(error); } else { throw error; } } export function Catch(handler: HandlerFunction, options?: Partial): CatchDecorator export function Catch(errorClass: any, handler: HandlerFunction, options?: Partial): CatchDecorator export function Catch(a, b?, c?) { let errorClass, handler: HandlerFunction, partialOptions: Partial; if (typeof b == 'function') { errorClass = a; handler = b; partialOptions = c; } else { handler = a; partialOptions = b; } const options: IntCatchOptions = { log: true, handler, errorClass, ...partialOptions, } return decorator_compatibility({ legacy(target, propertyKey, descriptor?) { // save a reference to the original method const originalMethod = descriptor.value // rewrite original method with custom wrapper descriptor.value = function (...args: any[]) { try { const result = originalMethod.apply(this, args) // check if method is asynchronous if (result && typeof result.then === 'function' && typeof result.catch === 'function') { // return promise return result.catch((error: any) => { handleError(this, error, options) }) } // return actual result return result } catch (error) { handleError(this, error, options) } } return descriptor }, stage3(originalMethod, context) { return function wrapped(...args: any[]) { try { const result = originalMethod.apply(this, args) // check if method is asynchronous if (result && typeof result.then === 'function' && typeof result.catch === 'function') { // return promise return result.catch((error: any) => { handleError(this, error, options) }) } // return actual result return result } catch (error) { handleError(this, error, options) } } }, }) } Catch.logger = (e: Error) => { console.error(e); } Catch.invokeHandler = (handler, err, ctx) => handler.call(ctx, err, ctx); try { const { captureException } = require('@sentry/core'); Catch.logger = (e: Error) => { console.error(e); captureException(e); } } catch { }