UNPKG

@sentry/react-native

Version:
127 lines 5.51 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { addExceptionMechanism, captureException, getClient, getCurrentScope, logger } from '@sentry/core'; import { createSyntheticError, isErrorLike } from '../utils/error'; import { RN_GLOBAL_OBJ } from '../utils/worldwide'; import { checkPromiseAndWarn, polyfillPromise, requireRejectionTracking } from './reactnativeerrorhandlersutils'; const INTEGRATION_NAME = 'ReactNativeErrorHandlers'; /** ReactNativeErrorHandlers Integration */ export const reactNativeErrorHandlersIntegration = (options = {}) => { return { name: INTEGRATION_NAME, setupOnce: () => setup(Object.assign({ onerror: true, onunhandledrejection: true, patchGlobalPromise: true }, options)), }; }; function setup(options) { options.onunhandledrejection && setupUnhandledRejectionsTracking(options.patchGlobalPromise); options.onerror && setupErrorUtilsGlobalHandler(); } /** * Setup unhandled promise rejection tracking */ function setupUnhandledRejectionsTracking(patchGlobalPromise) { if (patchGlobalPromise) { polyfillPromise(); } attachUnhandledRejectionHandler(); checkPromiseAndWarn(); } function attachUnhandledRejectionHandler() { const tracking = requireRejectionTracking(); const promiseRejectionTrackingOptions = { onUnhandled: (id, rejection = {}) => { // eslint-disable-next-line no-console console.warn(`Possible Unhandled Promise Rejection (id: ${id}):\n${rejection}`); }, onHandled: id => { // eslint-disable-next-line no-console console.warn(`Promise Rejection Handled (id: ${id})\n` + 'This means you can ignore any previous messages of the form ' + `"Possible Unhandled Promise Rejection (id: ${id}):"`); }, }; tracking.enable({ allRejections: true, onUnhandled: (id, error) => { if (__DEV__) { promiseRejectionTrackingOptions.onUnhandled(id, error); } captureException(error, { data: { id }, originalException: error, syntheticException: isErrorLike(error) ? undefined : createSyntheticError(), mechanism: { handled: true, type: 'onunhandledrejection' }, }); }, onHandled: (id) => { promiseRejectionTrackingOptions.onHandled(id); }, }); } function setupErrorUtilsGlobalHandler() { let handlingFatal = false; const errorUtils = RN_GLOBAL_OBJ.ErrorUtils; if (!errorUtils) { logger.warn('ErrorUtils not found. Can be caused by different environment for example react-native-web.'); return; } const defaultHandler = errorUtils.getGlobalHandler && errorUtils.getGlobalHandler(); // eslint-disable-next-line @typescript-eslint/no-explicit-any errorUtils.setGlobalHandler((error, isFatal) => __awaiter(this, void 0, void 0, function* () { // We want to handle fatals, but only in production mode. const shouldHandleFatal = isFatal && !__DEV__; if (shouldHandleFatal) { if (handlingFatal) { logger.log('Encountered multiple fatals in a row. The latest:', error); return; } handlingFatal = true; } const client = getClient(); if (!client) { logger.error('Sentry client is missing, the error event might be lost.', error); // If there is no client something is fishy, anyway we call the default handler defaultHandler(error, isFatal); return; } const hint = { originalException: error, attachments: getCurrentScope().getScopeData().attachments, }; const event = yield client.eventFromException(error, hint); if (isFatal) { event.level = 'fatal'; addExceptionMechanism(event, { handled: false, type: 'onerror', }); } else { event.level = 'error'; addExceptionMechanism(event, { handled: true, type: 'generic', }); } client.captureEvent(event, hint); if (__DEV__) { // If in dev, we call the default handler anyway and hope the error will be sent // Just for a better dev experience defaultHandler(error, isFatal); return; } void client.flush(client.getOptions().shutdownTimeout || 2000).then(() => { defaultHandler(error, isFatal); }, (reason) => { logger.error('[ReactNativeErrorHandlers] Error while flushing the event cache after uncaught error.', reason); }); })); } //# sourceMappingURL=reactnativeerrorhandlers.js.map