@sentry/browser
Version:
Official Sentry SDK for browsers
246 lines (213 loc) • 7.07 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
var core = require('@sentry/core');
var utils = require('@sentry/utils');
var eventbuilder = require('../eventbuilder.js');
var flags = require('../flags.js');
var helpers = require('../helpers.js');
/** Global handlers */
class GlobalHandlers {
/**
* @inheritDoc
*/
static __initStatic() {this.id = 'GlobalHandlers';}
/**
* @inheritDoc
*/
__init() {this.name = GlobalHandlers.id;}
/** JSDoc */
/**
* Stores references functions to installing handlers. Will set to undefined
* after they have been run so that they are not used twice.
*/
__init2() {this._installFunc = {
onerror: _installGlobalOnErrorHandler,
onunhandledrejection: _installGlobalOnUnhandledRejectionHandler,
};}
/** JSDoc */
constructor(options) {;GlobalHandlers.prototype.__init.call(this);GlobalHandlers.prototype.__init2.call(this);
this._options = {
onerror: true,
onunhandledrejection: true,
...options,
};
}
/**
* @inheritDoc
*/
setupOnce() {
Error.stackTraceLimit = 50;
var options = this._options;
// We can disable guard-for-in as we construct the options object above + do checks against
// `this._installFunc` for the property.
for (var key in options) {
var installFunc = this._installFunc[key ];
if (installFunc && options[key ]) {
globalHandlerLog(key);
installFunc();
this._installFunc[key ] = undefined;
}
}
}
} GlobalHandlers.__initStatic();
/** JSDoc */
function _installGlobalOnErrorHandler() {
utils.addInstrumentationHandler(
'error',
(data) => {
const [hub, stackParser, attachStacktrace] = getHubAndOptions();
if (!hub.getIntegration(GlobalHandlers)) {
return;
}
const { msg, url, line, column, error } = data;
if (helpers.shouldIgnoreOnError() || (error && error.__sentry_own_request__)) {
return;
}
var event =
error === undefined && utils.isString(msg)
? _eventFromIncompleteOnError(msg, url, line, column)
: _enhanceEventWithInitialFrame(
eventbuilder.eventFromUnknownInput(stackParser, error || msg, undefined, attachStacktrace, false),
url,
line,
column,
);
event.level = 'error';
addMechanismAndCapture(hub, error, event, 'onerror');
},
);
}
/** JSDoc */
function _installGlobalOnUnhandledRejectionHandler() {
utils.addInstrumentationHandler(
'unhandledrejection',
(e) => {
const [hub, stackParser, attachStacktrace] = getHubAndOptions();
if (!hub.getIntegration(GlobalHandlers)) {
return;
}
let 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
}
if (helpers.shouldIgnoreOnError() || (error && error.__sentry_own_request__)) {
return true;
}
var event = utils.isPrimitive(error)
? _eventFromRejectionWithPrimitive(error)
: eventbuilder.eventFromUnknownInput(stackParser, error, undefined, attachStacktrace, true);
event.level = 'error';
addMechanismAndCapture(hub, error, event, 'onunhandledrejection');
return;
},
);
}
/**
* Create an event from a promise rejection where the `reason` is a primitive.
*
* @param reason: The `reason` property of the promise rejection
* @returns An Event object with an appropriate `exception` value
*/
function _eventFromRejectionWithPrimitive(reason) {
return {
exception: {
values: [
{
type: 'UnhandledRejection',
// String() is needed because the Primitive type includes symbols (which can't be automatically stringified)
value: `Non-Error promise rejection captured with value: ${String(reason)}`,
},
],
},
};
}
/**
* This function creates a stack from an old, error-less onerror handler.
*/
function _eventFromIncompleteOnError(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
let message = utils.isErrorEvent(msg) ? msg.message : msg;
let name = 'Error';
var groups = message.match(ERROR_TYPES_RE);
if (groups) {
name = groups[1];
message = groups[2];
}
var event = {
exception: {
values: [
{
type: name,
value: message,
},
],
},
};
return _enhanceEventWithInitialFrame(event, url, line, column);
}
/** JSDoc */
function _enhanceEventWithInitialFrame(event, url, line, column) {
// event.exception
var e = (event.exception = event.exception || {});
// event.exception.values
var ev = (e.values = e.values || []);
// event.exception.values[0]
var ev0 = (ev[0] = ev[0] || {});
// event.exception.values[0].stacktrace
var ev0s = (ev0.stacktrace = ev0.stacktrace || {});
// event.exception.values[0].stacktrace.frames
var ev0sf = (ev0s.frames = ev0s.frames || []);
var colno = isNaN(parseInt(column, 10)) ? undefined : column;
var lineno = isNaN(parseInt(line, 10)) ? undefined : line;
var filename = utils.isString(url) && url.length > 0 ? url : utils.getLocationHref();
// event.exception.values[0].stacktrace.frames
if (ev0sf.length === 0) {
ev0sf.push({
colno,
filename,
function: '?',
in_app: true,
lineno,
});
}
return event;
}
function globalHandlerLog(type) {
flags.IS_DEBUG_BUILD && utils.logger.log(`Global Handler attached: ${type}`);
}
function addMechanismAndCapture(hub, error, event, type) {
utils.addExceptionMechanism(event, {
handled: false,
type,
});
hub.captureEvent(event, {
originalException: error,
});
}
function getHubAndOptions() {
var hub = core.getCurrentHub();
var client = hub.getClient();
var options = (client && client.getOptions()) || {
stackParser: () => [],
attachStacktrace: false,
};
return [hub, options.stackParser, options.attachStacktrace];
}
exports.GlobalHandlers = GlobalHandlers;
//# sourceMappingURL=globalhandlers.js.map