123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- import { defineIntegration, convertIntegrationFnToClass, getClient, captureException } from '@sentry/core';
- import { logger } from '@sentry/utils';
- import { DEBUG_BUILD } from '../debug-build.js';
- import { logAndExitProcess } from './utils/errorhandling.js';
- const INTEGRATION_NAME = 'OnUncaughtException';
- const _onUncaughtExceptionIntegration = ((options = {}) => {
- const _options = {
- exitEvenIfOtherHandlersAreRegistered: true,
- ...options,
- };
- return {
- name: INTEGRATION_NAME,
-
- setupOnce() {},
- setup(client) {
- global.process.on('uncaughtException', makeErrorHandler(client, _options));
- },
- };
- }) ;
- const onUncaughtExceptionIntegration = defineIntegration(_onUncaughtExceptionIntegration);
- const OnUncaughtException = convertIntegrationFnToClass(
- INTEGRATION_NAME,
- onUncaughtExceptionIntegration,
- )
- ;
- function makeErrorHandler(client, options) {
- const timeout = 2000;
- let caughtFirstError = false;
- let caughtSecondError = false;
- let calledFatalError = false;
- let firstError;
- const clientOptions = client.getOptions();
- return Object.assign(
- (error) => {
- let onFatalError = logAndExitProcess;
- if (options.onFatalError) {
- onFatalError = options.onFatalError;
- } else if (clientOptions.onFatalError) {
- onFatalError = clientOptions.onFatalError ;
- }
-
-
-
-
-
- const userProvidedListenersCount = (
- global.process.listeners('uncaughtException')
- ).reduce((acc, listener) => {
- if (
-
- listener.name === 'domainUncaughtExceptionClear' ||
- (listener.tag && listener.tag === 'sentry_tracingErrorCallback') ||
- (listener )._errorHandler
- ) {
- return acc;
- } else {
- return acc + 1;
- }
- }, 0);
- const processWouldExit = userProvidedListenersCount === 0;
- const shouldApplyFatalHandlingLogic = options.exitEvenIfOtherHandlersAreRegistered || processWouldExit;
- if (!caughtFirstError) {
-
-
-
- firstError = error;
- caughtFirstError = true;
- if (getClient() === client) {
- captureException(error, {
- originalException: error,
- captureContext: {
- level: 'fatal',
- },
- mechanism: {
- handled: false,
- type: 'onuncaughtexception',
- },
- });
- }
- if (!calledFatalError && shouldApplyFatalHandlingLogic) {
- calledFatalError = true;
- onFatalError(error);
- }
- } else {
- if (shouldApplyFatalHandlingLogic) {
- if (calledFatalError) {
-
- DEBUG_BUILD &&
- logger.warn(
- 'uncaught exception after calling fatal error shutdown callback - this is bad! forcing shutdown',
- );
- logAndExitProcess(error);
- } else if (!caughtSecondError) {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- caughtSecondError = true;
- setTimeout(() => {
- if (!calledFatalError) {
-
- calledFatalError = true;
- onFatalError(firstError, error);
- }
- }, timeout);
- }
- }
- }
- },
- { _errorHandler: true },
- );
- }
- export { OnUncaughtException, makeErrorHandler, onUncaughtExceptionIntegration };
|