@sentry/browser
Version:
Official Sentry SDK for browsers
200 lines • 8.67 kB
JavaScript
import { __assign } from "tslib";
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { getCurrentHub } from '@sentry/core';
import { Severity } from '@sentry/types';
import { addExceptionMechanism, addInstrumentationHandler, getLocationHref, isErrorEvent, isPrimitive, isString, logger, } from '@sentry/utils';
import { eventFromUnknownInput } from '../eventbuilder';
import { shouldIgnoreOnError } from '../helpers';
/** Global handlers */
var GlobalHandlers = /** @class */ (function () {
/** JSDoc */
function GlobalHandlers(options) {
/**
* @inheritDoc
*/
this.name = GlobalHandlers.id;
/** JSDoc */
this._onErrorHandlerInstalled = false;
/** JSDoc */
this._onUnhandledRejectionHandlerInstalled = false;
this._options = __assign({ onerror: true, onunhandledrejection: true }, options);
}
/**
* @inheritDoc
*/
GlobalHandlers.prototype.setupOnce = function () {
Error.stackTraceLimit = 50;
if (this._options.onerror) {
logger.log('Global Handler attached: onerror');
this._installGlobalOnErrorHandler();
}
if (this._options.onunhandledrejection) {
logger.log('Global Handler attached: onunhandledrejection');
this._installGlobalOnUnhandledRejectionHandler();
}
};
/** JSDoc */
GlobalHandlers.prototype._installGlobalOnErrorHandler = function () {
var _this = this;
if (this._onErrorHandlerInstalled) {
return;
}
addInstrumentationHandler({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
callback: function (data) {
var error = data.error;
var currentHub = getCurrentHub();
var hasIntegration = currentHub.getIntegration(GlobalHandlers);
var isFailedOwnDelivery = error && error.__sentry_own_request__ === true;
if (!hasIntegration || shouldIgnoreOnError() || isFailedOwnDelivery) {
return;
}
var client = currentHub.getClient();
var event = isPrimitive(error)
? _this._eventFromIncompleteOnError(data.msg, data.url, data.line, data.column)
: _this._enhanceEventWithInitialFrame(eventFromUnknownInput(error, undefined, {
attachStacktrace: client && client.getOptions().attachStacktrace,
rejection: false,
}), data.url, data.line, data.column);
addExceptionMechanism(event, {
handled: false,
type: 'onerror',
});
currentHub.captureEvent(event, {
originalException: error,
});
},
type: 'error',
});
this._onErrorHandlerInstalled = true;
};
/** JSDoc */
GlobalHandlers.prototype._installGlobalOnUnhandledRejectionHandler = function () {
var _this = this;
if (this._onUnhandledRejectionHandlerInstalled) {
return;
}
addInstrumentationHandler({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
callback: function (e) {
var error = e;
// dig the object of the rejection out of known event types
try {
// PromiseRejectionEvents store the object of the rejection under 'reason'
// see https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent
if ('reason' in e) {
error = e.reason;
}
// something, somewhere, (likely a browser extension) effectively casts PromiseRejectionEvents
// to CustomEvents, moving the `promise` and `reason` attributes of the PRE into
// the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec
// see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and
// https://github.com/getsentry/sentry-javascript/issues/2380
else if ('detail' in e && 'reason' in e.detail) {
error = e.detail.reason;
}
}
catch (_oO) {
// no-empty
}
var currentHub = getCurrentHub();
var hasIntegration = currentHub.getIntegration(GlobalHandlers);
var isFailedOwnDelivery = error && error.__sentry_own_request__ === true;
if (!hasIntegration || shouldIgnoreOnError() || isFailedOwnDelivery) {
return true;
}
var client = currentHub.getClient();
var event = isPrimitive(error)
? _this._eventFromIncompleteRejection(error)
: eventFromUnknownInput(error, undefined, {
attachStacktrace: client && client.getOptions().attachStacktrace,
rejection: true,
});
event.level = Severity.Error;
addExceptionMechanism(event, {
handled: false,
type: 'onunhandledrejection',
});
currentHub.captureEvent(event, {
originalException: error,
});
return;
},
type: 'unhandledrejection',
});
this._onUnhandledRejectionHandlerInstalled = true;
};
/**
* This function creates a stack from an old, error-less onerror handler.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
GlobalHandlers.prototype._eventFromIncompleteOnError = function (msg, url, line, column) {
var ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
// If 'message' is ErrorEvent, get real message from inside
var message = isErrorEvent(msg) ? msg.message : msg;
var name;
if (isString(message)) {
var groups = message.match(ERROR_TYPES_RE);
if (groups) {
name = groups[1];
message = groups[2];
}
}
var event = {
exception: {
values: [
{
type: name || 'Error',
value: message,
},
],
},
};
return this._enhanceEventWithInitialFrame(event, url, line, column);
};
/**
* This function creates an Event from an TraceKitStackTrace that has part of it missing.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
GlobalHandlers.prototype._eventFromIncompleteRejection = function (error) {
return {
exception: {
values: [
{
type: 'UnhandledRejection',
value: "Non-Error promise rejection captured with value: " + error,
},
],
},
};
};
/** JSDoc */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
GlobalHandlers.prototype._enhanceEventWithInitialFrame = function (event, url, line, column) {
event.exception = event.exception || {};
event.exception.values = event.exception.values || [];
event.exception.values[0] = event.exception.values[0] || {};
event.exception.values[0].stacktrace = event.exception.values[0].stacktrace || {};
event.exception.values[0].stacktrace.frames = event.exception.values[0].stacktrace.frames || [];
var colno = isNaN(parseInt(column, 10)) ? undefined : column;
var lineno = isNaN(parseInt(line, 10)) ? undefined : line;
var filename = isString(url) && url.length > 0 ? url : getLocationHref();
if (event.exception.values[0].stacktrace.frames.length === 0) {
event.exception.values[0].stacktrace.frames.push({
colno: colno,
filename: filename,
function: '?',
in_app: true,
lineno: lineno,
});
}
return event;
};
/**
* @inheritDoc
*/
GlobalHandlers.id = 'GlobalHandlers';
return GlobalHandlers;
}());
export { GlobalHandlers };
//# sourceMappingURL=globalhandlers.js.map