import { CatchResult } from './CatchResult'; import { ErrorEventHandler, IErrorEventHandler } from './ErrorEventHandler'; import * as React from 'react'; type UseErrorEventCatcherProps = { apiUrl: string; enabled?: boolean; loading?: boolean; catcherFn?: (error: string | any) => CatchResult; errorHandler?: IErrorEventHandler; }; function useErrorEventCatcher({ enabled = true, apiUrl, loading, catcherFn = (error) => new CatchResult({ catch: error != undefined, display: false, log: error != undefined, error }), ...props }: UseErrorEventCatcherProps) { const errorHandler = React.useMemo(() => { if (props.errorHandler) { return props.errorHandler; } return new ErrorEventHandler({ apiUrl }); }, [apiUrl, props.errorHandler]); const consoleError = console.error; const handleError = React.useCallback( function (event: ErrorEvent | string, ...args: any[]) { if (!event) { return false; } const catchResult = catcherFn( event instanceof ErrorEvent ? event : event?.toString()?.replace(/%s/g, () => args.shift()) ); if (catchResult.isCatched()) { return false; } if (catchResult.logError()) { if (event instanceof ErrorEvent) { errorHandler.handle(event); } else { errorHandler.handle(new ErrorEvent('window.onerror', { error: event, message: event.toString() })); } } if (catchResult.displayError()) { // eslint-disable-next-line prefer-rest-params consoleError.apply(console, arguments as any); } return false; }, [catcherFn, errorHandler, consoleError] ); React.useEffect(() => { window.removeEventListener('error', handleError); window.addEventListener('error', handleError); console.error = handleError; return () => { window.removeEventListener('error', handleError); console.error = consoleError; }; }, [handleError, consoleError]); return true; } export { useErrorEventCatcher };