1import React from 'react';
2
3import ExceptionsManager from './modules/ExceptionsManager';
4
5function useStackTraceLimit(limit: number) {
6  const current = React.useRef(0);
7  React.useEffect(() => {
8    try {
9      // @ts-expect-error: StackTraceLimit is not defined in the Error type
10      const currentLimit = Error.stackTraceLimit;
11      // @ts-expect-error: StackTraceLimit is not defined in the Error type
12      Error.stackTraceLimit = limit;
13      current.current = currentLimit;
14    } catch {}
15    return () => {
16      try {
17        // @ts-expect-error: StackTraceLimit is not defined in the Error type
18        Error.stackTraceLimit = current.current;
19      } catch {}
20    };
21  }, [limit]);
22}
23
24export function useRejectionHandler() {
25  const hasError = React.useRef(false);
26
27  useStackTraceLimit(35);
28
29  React.useEffect(() => {
30    function onUnhandledError(ev: ErrorEvent) {
31      hasError.current = true;
32
33      const error = ev?.error;
34      if (!error || !(error instanceof Error) || typeof error.stack !== 'string') {
35        return;
36      }
37
38      ExceptionsManager.handleException(error);
39    }
40
41    function onUnhandledRejection(ev: PromiseRejectionEvent) {
42      hasError.current = true;
43
44      const reason = ev?.reason;
45      if (!reason || !(reason instanceof Error) || typeof reason.stack !== 'string') {
46        return;
47      }
48
49      ExceptionsManager.handleException(reason);
50    }
51
52    window.addEventListener('unhandledrejection', onUnhandledRejection);
53    window.addEventListener('error', onUnhandledError);
54    return () => {
55      window.removeEventListener('error', onUnhandledError);
56      window.removeEventListener('unhandledrejection', onUnhandledRejection);
57    };
58  }, []);
59
60  return hasError;
61}
62