UNPKG

7.97 kBSource Map (JSON)View Raw
1{"version":3,"file":"onuncaughtexception.js","sourceRoot":"","sources":["../../src/integrations/onuncaughtexception.ts"],"names":[],"mappings":"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","sourcesContent":["import { getCurrentHub, Scope } from '@sentry/core';\nimport { Integration, Severity } from '@sentry/types';\nimport { logger } from '@sentry/utils';\n\nimport { NodeClient } from '../client';\nimport { logAndExitProcess } from './utils/errorhandling';\n\ntype OnFatalErrorHandler = (firstError: Error, secondError?: Error) => void;\n\n/** Global Promise Rejection handler */\nexport class OnUncaughtException implements Integration {\n /**\n * @inheritDoc\n */\n public static id: string = 'OnUncaughtException';\n\n /**\n * @inheritDoc\n */\n public name: string = OnUncaughtException.id;\n\n /**\n * @inheritDoc\n */\n public readonly handler: (error: Error) => void = this._makeErrorHandler();\n\n /**\n * @inheritDoc\n */\n public constructor(\n private readonly _options: {\n /**\n * Default onFatalError handler\n * @param firstError Error that has been thrown\n * @param secondError If this was called multiple times this will be set\n */\n onFatalError?(firstError: Error, secondError?: Error): void;\n } = {},\n ) {}\n /**\n * @inheritDoc\n */\n public setupOnce(): void {\n global.process.on('uncaughtException', this.handler.bind(this));\n }\n\n /**\n * @hidden\n */\n private _makeErrorHandler(): (error: Error) => void {\n const timeout = 2000;\n let caughtFirstError: boolean = false;\n let caughtSecondError: boolean = false;\n let calledFatalError: boolean = false;\n let firstError: Error;\n\n return (error: Error): void => {\n let onFatalError: OnFatalErrorHandler = logAndExitProcess;\n const client = getCurrentHub().getClient<NodeClient>();\n\n if (this._options.onFatalError) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n onFatalError = this._options.onFatalError;\n } else if (client && client.getOptions().onFatalError) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n onFatalError = client.getOptions().onFatalError as OnFatalErrorHandler;\n }\n\n if (!caughtFirstError) {\n const hub = getCurrentHub();\n\n // this is the first uncaught error and the ultimate reason for shutting down\n // we want to do absolutely everything possible to ensure it gets captured\n // also we want to make sure we don't go recursion crazy if more errors happen after this one\n firstError = error;\n caughtFirstError = true;\n\n if (hub.getIntegration(OnUncaughtException)) {\n hub.withScope((scope: Scope) => {\n scope.setLevel(Severity.Fatal);\n hub.captureException(error, {\n originalException: error,\n data: { mechanism: { handled: false, type: 'onuncaughtexception' } },\n });\n if (!calledFatalError) {\n calledFatalError = true;\n onFatalError(error);\n }\n });\n } else {\n if (!calledFatalError) {\n calledFatalError = true;\n onFatalError(error);\n }\n }\n } else if (calledFatalError) {\n // we hit an error *after* calling onFatalError - pretty boned at this point, just shut it down\n logger.warn('uncaught exception after calling fatal error shutdown callback - this is bad! forcing shutdown');\n logAndExitProcess(error);\n } else if (!caughtSecondError) {\n // two cases for how we can hit this branch:\n // - capturing of first error blew up and we just caught the exception from that\n // - quit trying to capture, proceed with shutdown\n // - a second independent error happened while waiting for first error to capture\n // - want to avoid causing premature shutdown before first error capture finishes\n // it's hard to immediately tell case 1 from case 2 without doing some fancy/questionable domain stuff\n // so let's instead just delay a bit before we proceed with our action here\n // in case 1, we just wait a bit unnecessarily but ultimately do the same thing\n // in case 2, the delay hopefully made us wait long enough for the capture to finish\n // two potential nonideal outcomes:\n // nonideal case 1: capturing fails fast, we sit around for a few seconds unnecessarily before proceeding correctly by calling onFatalError\n // nonideal case 2: case 2 happens, 1st error is captured but slowly, timeout completes before capture and we treat second error as the sendErr of (nonexistent) failure from trying to capture first error\n // note that after hitting this branch, we might catch more errors where (caughtSecondError && !calledFatalError)\n // we ignore them - they don't matter to us, we're just waiting for the second error timeout to finish\n caughtSecondError = true;\n setTimeout(() => {\n if (!calledFatalError) {\n // it was probably case 1, let's treat err as the sendErr and call onFatalError\n calledFatalError = true;\n onFatalError(firstError, error);\n } else {\n // it was probably case 2, our first error finished capturing while we waited, cool, do nothing\n }\n }, timeout); // capturing could take at least sendTimeout to fail, plus an arbitrary second for how long it takes to collect surrounding source etc\n }\n };\n }\n}\n"]}
\No newline at end of file