forked from off-topic/apps.apple.com
init commit
This commit is contained in:
320
shared/logger/node_modules/@sentry/browser/esm/integrations/breadcrumbs.js
generated
vendored
Normal file
320
shared/logger/node_modules/@sentry/browser/esm/integrations/breadcrumbs.js
generated
vendored
Normal file
@@ -0,0 +1,320 @@
|
||||
import { getCurrentHub } from '@sentry/core';
|
||||
import { addInstrumentationHandler, getEventDescription, severityLevelFromString, safeJoin, SENTRY_XHR_DATA_KEY, parseUrl, logger, htmlTreeAsString } from '@sentry/utils';
|
||||
import { WINDOW } from '../helpers.js';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
|
||||
/** maxStringLength gets capped to prevent 100 breadcrumbs exceeding 1MB event payload size */
|
||||
const MAX_ALLOWED_STRING_LENGTH = 1024;
|
||||
|
||||
const BREADCRUMB_INTEGRATION_ID = 'Breadcrumbs';
|
||||
|
||||
/**
|
||||
* Default Breadcrumbs instrumentations
|
||||
* TODO: Deprecated - with v6, this will be renamed to `Instrument`
|
||||
*/
|
||||
class Breadcrumbs {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
static __initStatic() {this.id = BREADCRUMB_INTEGRATION_ID;}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
__init() {this.name = Breadcrumbs.id;}
|
||||
|
||||
/**
|
||||
* Options of the breadcrumbs integration.
|
||||
*/
|
||||
// This field is public, because we use it in the browser client to check if the `sentry` option is enabled.
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
constructor(options) {Breadcrumbs.prototype.__init.call(this);
|
||||
this.options = {
|
||||
console: true,
|
||||
dom: true,
|
||||
fetch: true,
|
||||
history: true,
|
||||
sentry: true,
|
||||
xhr: true,
|
||||
...options,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instrument browser built-ins w/ breadcrumb capturing
|
||||
* - Console API
|
||||
* - DOM API (click/typing)
|
||||
* - XMLHttpRequest API
|
||||
* - Fetch API
|
||||
* - History API
|
||||
*/
|
||||
setupOnce() {
|
||||
if (this.options.console) {
|
||||
addInstrumentationHandler('console', _consoleBreadcrumb);
|
||||
}
|
||||
if (this.options.dom) {
|
||||
addInstrumentationHandler('dom', _domBreadcrumb(this.options.dom));
|
||||
}
|
||||
if (this.options.xhr) {
|
||||
addInstrumentationHandler('xhr', _xhrBreadcrumb);
|
||||
}
|
||||
if (this.options.fetch) {
|
||||
addInstrumentationHandler('fetch', _fetchBreadcrumb);
|
||||
}
|
||||
if (this.options.history) {
|
||||
addInstrumentationHandler('history', _historyBreadcrumb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a breadcrumb for Sentry events or transactions if this option is enabled.
|
||||
*/
|
||||
addSentryBreadcrumb(event) {
|
||||
if (this.options.sentry) {
|
||||
getCurrentHub().addBreadcrumb(
|
||||
{
|
||||
category: `sentry.${event.type === 'transaction' ? 'transaction' : 'event'}`,
|
||||
event_id: event.event_id,
|
||||
level: event.level,
|
||||
message: getEventDescription(event),
|
||||
},
|
||||
{
|
||||
event,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
} Breadcrumbs.__initStatic();
|
||||
|
||||
/**
|
||||
* A HOC that creaes a function that creates breadcrumbs from DOM API calls.
|
||||
* This is a HOC so that we get access to dom options in the closure.
|
||||
*/
|
||||
function _domBreadcrumb(dom) {
|
||||
function _innerDomBreadcrumb(handlerData) {
|
||||
let target;
|
||||
let keyAttrs = typeof dom === 'object' ? dom.serializeAttribute : undefined;
|
||||
|
||||
let maxStringLength =
|
||||
typeof dom === 'object' && typeof dom.maxStringLength === 'number' ? dom.maxStringLength : undefined;
|
||||
if (maxStringLength && maxStringLength > MAX_ALLOWED_STRING_LENGTH) {
|
||||
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
|
||||
logger.warn(
|
||||
`\`dom.maxStringLength\` cannot exceed ${MAX_ALLOWED_STRING_LENGTH}, but a value of ${maxStringLength} was configured. Sentry will use ${MAX_ALLOWED_STRING_LENGTH} instead.`,
|
||||
);
|
||||
maxStringLength = MAX_ALLOWED_STRING_LENGTH;
|
||||
}
|
||||
|
||||
if (typeof keyAttrs === 'string') {
|
||||
keyAttrs = [keyAttrs];
|
||||
}
|
||||
|
||||
// Accessing event.target can throw (see getsentry/raven-js#838, #768)
|
||||
try {
|
||||
const event = handlerData.event ;
|
||||
target = _isEvent(event)
|
||||
? htmlTreeAsString(event.target, { keyAttrs, maxStringLength })
|
||||
: htmlTreeAsString(event, { keyAttrs, maxStringLength });
|
||||
} catch (e) {
|
||||
target = '<unknown>';
|
||||
}
|
||||
|
||||
if (target.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
getCurrentHub().addBreadcrumb(
|
||||
{
|
||||
category: `ui.${handlerData.name}`,
|
||||
message: target,
|
||||
},
|
||||
{
|
||||
event: handlerData.event,
|
||||
name: handlerData.name,
|
||||
global: handlerData.global,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return _innerDomBreadcrumb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates breadcrumbs from console API calls
|
||||
*/
|
||||
function _consoleBreadcrumb(handlerData) {
|
||||
// This is a hack to fix a Vue3-specific bug that causes an infinite loop of
|
||||
// console warnings. This happens when a Vue template is rendered with
|
||||
// an undeclared variable, which we try to stringify, ultimately causing
|
||||
// Vue to issue another warning which repeats indefinitely.
|
||||
// see: https://github.com/getsentry/sentry-javascript/pull/6010
|
||||
// see: https://github.com/getsentry/sentry-javascript/issues/5916
|
||||
for (let i = 0; i < handlerData.args.length; i++) {
|
||||
if (handlerData.args[i] === 'ref=Ref<') {
|
||||
handlerData.args[i + 1] = 'viewRef';
|
||||
break;
|
||||
}
|
||||
}
|
||||
const breadcrumb = {
|
||||
category: 'console',
|
||||
data: {
|
||||
arguments: handlerData.args,
|
||||
logger: 'console',
|
||||
},
|
||||
level: severityLevelFromString(handlerData.level),
|
||||
message: safeJoin(handlerData.args, ' '),
|
||||
};
|
||||
|
||||
if (handlerData.level === 'assert') {
|
||||
if (handlerData.args[0] === false) {
|
||||
breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;
|
||||
breadcrumb.data.arguments = handlerData.args.slice(1);
|
||||
} else {
|
||||
// Don't capture a breadcrumb for passed assertions
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentHub().addBreadcrumb(breadcrumb, {
|
||||
input: handlerData.args,
|
||||
level: handlerData.level,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates breadcrumbs from XHR API calls
|
||||
*/
|
||||
function _xhrBreadcrumb(handlerData) {
|
||||
const { startTimestamp, endTimestamp } = handlerData;
|
||||
|
||||
const sentryXhrData = handlerData.xhr[SENTRY_XHR_DATA_KEY];
|
||||
|
||||
// We only capture complete, non-sentry requests
|
||||
if (!startTimestamp || !endTimestamp || !sentryXhrData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { method, url, status_code, body } = sentryXhrData;
|
||||
|
||||
const data = {
|
||||
method,
|
||||
url,
|
||||
status_code,
|
||||
};
|
||||
|
||||
const hint = {
|
||||
xhr: handlerData.xhr,
|
||||
input: body,
|
||||
startTimestamp,
|
||||
endTimestamp,
|
||||
};
|
||||
|
||||
getCurrentHub().addBreadcrumb(
|
||||
{
|
||||
category: 'xhr',
|
||||
data,
|
||||
type: 'http',
|
||||
},
|
||||
hint,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates breadcrumbs from fetch API calls
|
||||
*/
|
||||
function _fetchBreadcrumb(handlerData) {
|
||||
const { startTimestamp, endTimestamp } = handlerData;
|
||||
|
||||
// We only capture complete fetch requests
|
||||
if (!endTimestamp) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {
|
||||
// We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)
|
||||
return;
|
||||
}
|
||||
|
||||
if (handlerData.error) {
|
||||
const data = handlerData.fetchData;
|
||||
const hint = {
|
||||
data: handlerData.error,
|
||||
input: handlerData.args,
|
||||
startTimestamp,
|
||||
endTimestamp,
|
||||
};
|
||||
|
||||
getCurrentHub().addBreadcrumb(
|
||||
{
|
||||
category: 'fetch',
|
||||
data,
|
||||
level: 'error',
|
||||
type: 'http',
|
||||
},
|
||||
hint,
|
||||
);
|
||||
} else {
|
||||
const data = {
|
||||
...handlerData.fetchData,
|
||||
status_code: handlerData.response && handlerData.response.status,
|
||||
};
|
||||
const hint = {
|
||||
input: handlerData.args,
|
||||
response: handlerData.response,
|
||||
startTimestamp,
|
||||
endTimestamp,
|
||||
};
|
||||
getCurrentHub().addBreadcrumb(
|
||||
{
|
||||
category: 'fetch',
|
||||
data,
|
||||
type: 'http',
|
||||
},
|
||||
hint,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates breadcrumbs from history API calls
|
||||
*/
|
||||
function _historyBreadcrumb(handlerData) {
|
||||
let from = handlerData.from;
|
||||
let to = handlerData.to;
|
||||
const parsedLoc = parseUrl(WINDOW.location.href);
|
||||
let parsedFrom = parseUrl(from);
|
||||
const parsedTo = parseUrl(to);
|
||||
|
||||
// Initial pushState doesn't provide `from` information
|
||||
if (!parsedFrom.path) {
|
||||
parsedFrom = parsedLoc;
|
||||
}
|
||||
|
||||
// Use only the path component of the URL if the URL matches the current
|
||||
// document (almost all the time when using pushState)
|
||||
if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {
|
||||
to = parsedTo.relative;
|
||||
}
|
||||
if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {
|
||||
from = parsedFrom.relative;
|
||||
}
|
||||
|
||||
getCurrentHub().addBreadcrumb({
|
||||
category: 'navigation',
|
||||
data: {
|
||||
from,
|
||||
to,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function _isEvent(event) {
|
||||
return !!event && !!(event ).target;
|
||||
}
|
||||
|
||||
export { BREADCRUMB_INTEGRATION_ID, Breadcrumbs };
|
||||
//# sourceMappingURL=breadcrumbs.js.map
|
||||
211
shared/logger/node_modules/@sentry/browser/esm/integrations/dedupe.js
generated
vendored
Normal file
211
shared/logger/node_modules/@sentry/browser/esm/integrations/dedupe.js
generated
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
import { logger } from '@sentry/utils';
|
||||
|
||||
/** Deduplication filter */
|
||||
class Dedupe {constructor() { Dedupe.prototype.__init.call(this); }
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
static __initStatic() {this.id = 'Dedupe';}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
__init() {this.name = Dedupe.id;}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
setupOnce(addGlobalEventProcessor, getCurrentHub) {
|
||||
const eventProcessor = currentEvent => {
|
||||
// We want to ignore any non-error type events, e.g. transactions or replays
|
||||
// These should never be deduped, and also not be compared against as _previousEvent.
|
||||
if (currentEvent.type) {
|
||||
return currentEvent;
|
||||
}
|
||||
|
||||
const self = getCurrentHub().getIntegration(Dedupe);
|
||||
if (self) {
|
||||
// Juuust in case something goes wrong
|
||||
try {
|
||||
if (_shouldDropEvent(currentEvent, self._previousEvent)) {
|
||||
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('Event dropped due to being a duplicate of previously captured event.');
|
||||
return null;
|
||||
}
|
||||
} catch (_oO) {
|
||||
return (self._previousEvent = currentEvent);
|
||||
}
|
||||
|
||||
return (self._previousEvent = currentEvent);
|
||||
}
|
||||
return currentEvent;
|
||||
};
|
||||
|
||||
eventProcessor.id = this.name;
|
||||
addGlobalEventProcessor(eventProcessor);
|
||||
}
|
||||
} Dedupe.__initStatic();
|
||||
|
||||
/** JSDoc */
|
||||
function _shouldDropEvent(currentEvent, previousEvent) {
|
||||
if (!previousEvent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_isSameMessageEvent(currentEvent, previousEvent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_isSameExceptionEvent(currentEvent, previousEvent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** JSDoc */
|
||||
function _isSameMessageEvent(currentEvent, previousEvent) {
|
||||
const currentMessage = currentEvent.message;
|
||||
const previousMessage = previousEvent.message;
|
||||
|
||||
// If neither event has a message property, they were both exceptions, so bail out
|
||||
if (!currentMessage && !previousMessage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If only one event has a stacktrace, but not the other one, they are not the same
|
||||
if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentMessage !== previousMessage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_isSameFingerprint(currentEvent, previousEvent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_isSameStacktrace(currentEvent, previousEvent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** JSDoc */
|
||||
function _isSameExceptionEvent(currentEvent, previousEvent) {
|
||||
const previousException = _getExceptionFromEvent(previousEvent);
|
||||
const currentException = _getExceptionFromEvent(currentEvent);
|
||||
|
||||
if (!previousException || !currentException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (previousException.type !== currentException.type || previousException.value !== currentException.value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_isSameFingerprint(currentEvent, previousEvent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_isSameStacktrace(currentEvent, previousEvent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** JSDoc */
|
||||
function _isSameStacktrace(currentEvent, previousEvent) {
|
||||
let currentFrames = _getFramesFromEvent(currentEvent);
|
||||
let previousFrames = _getFramesFromEvent(previousEvent);
|
||||
|
||||
// If neither event has a stacktrace, they are assumed to be the same
|
||||
if (!currentFrames && !previousFrames) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If only one event has a stacktrace, but not the other one, they are not the same
|
||||
if ((currentFrames && !previousFrames) || (!currentFrames && previousFrames)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
currentFrames = currentFrames ;
|
||||
previousFrames = previousFrames ;
|
||||
|
||||
// If number of frames differ, they are not the same
|
||||
if (previousFrames.length !== currentFrames.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, compare the two
|
||||
for (let i = 0; i < previousFrames.length; i++) {
|
||||
const frameA = previousFrames[i];
|
||||
const frameB = currentFrames[i];
|
||||
|
||||
if (
|
||||
frameA.filename !== frameB.filename ||
|
||||
frameA.lineno !== frameB.lineno ||
|
||||
frameA.colno !== frameB.colno ||
|
||||
frameA.function !== frameB.function
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** JSDoc */
|
||||
function _isSameFingerprint(currentEvent, previousEvent) {
|
||||
let currentFingerprint = currentEvent.fingerprint;
|
||||
let previousFingerprint = previousEvent.fingerprint;
|
||||
|
||||
// If neither event has a fingerprint, they are assumed to be the same
|
||||
if (!currentFingerprint && !previousFingerprint) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If only one event has a fingerprint, but not the other one, they are not the same
|
||||
if ((currentFingerprint && !previousFingerprint) || (!currentFingerprint && previousFingerprint)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
currentFingerprint = currentFingerprint ;
|
||||
previousFingerprint = previousFingerprint ;
|
||||
|
||||
// Otherwise, compare the two
|
||||
try {
|
||||
return !!(currentFingerprint.join('') === previousFingerprint.join(''));
|
||||
} catch (_oO) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** JSDoc */
|
||||
function _getExceptionFromEvent(event) {
|
||||
return event.exception && event.exception.values && event.exception.values[0];
|
||||
}
|
||||
|
||||
/** JSDoc */
|
||||
function _getFramesFromEvent(event) {
|
||||
const exception = event.exception;
|
||||
|
||||
if (exception) {
|
||||
try {
|
||||
// @ts-ignore Object could be undefined
|
||||
return exception.values[0].stacktrace.frames;
|
||||
} catch (_oO) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export { Dedupe };
|
||||
//# sourceMappingURL=dedupe.js.map
|
||||
248
shared/logger/node_modules/@sentry/browser/esm/integrations/globalhandlers.js
generated
vendored
Normal file
248
shared/logger/node_modules/@sentry/browser/esm/integrations/globalhandlers.js
generated
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
import { getCurrentHub } from '@sentry/core';
|
||||
import { addInstrumentationHandler, isString, isPrimitive, isErrorEvent, getLocationHref, logger, addExceptionMechanism } from '@sentry/utils';
|
||||
import { eventFromUnknownInput } from '../eventbuilder.js';
|
||||
import { shouldIgnoreOnError } from '../helpers.js';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
|
||||
/** 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;
|
||||
const options = this._options;
|
||||
|
||||
// We can disable guard-for-in as we construct the options object above + do checks against
|
||||
// `this._installFunc` for the property.
|
||||
// eslint-disable-next-line guard-for-in
|
||||
for (const key in options) {
|
||||
const installFunc = this._installFunc[key ];
|
||||
if (installFunc && options[key ]) {
|
||||
globalHandlerLog(key);
|
||||
installFunc();
|
||||
this._installFunc[key ] = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
} GlobalHandlers.__initStatic();
|
||||
|
||||
/** JSDoc */
|
||||
function _installGlobalOnErrorHandler() {
|
||||
addInstrumentationHandler(
|
||||
'error',
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(data) => {
|
||||
const [hub, stackParser, attachStacktrace] = getHubAndOptions();
|
||||
if (!hub.getIntegration(GlobalHandlers)) {
|
||||
return;
|
||||
}
|
||||
const { msg, url, line, column, error } = data;
|
||||
if (shouldIgnoreOnError() || (error && error.__sentry_own_request__)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const event =
|
||||
error === undefined && isString(msg)
|
||||
? _eventFromIncompleteOnError(msg, url, line, column)
|
||||
: _enhanceEventWithInitialFrame(
|
||||
eventFromUnknownInput(stackParser, error || msg, undefined, attachStacktrace, false),
|
||||
url,
|
||||
line,
|
||||
column,
|
||||
);
|
||||
|
||||
event.level = 'error';
|
||||
|
||||
addMechanismAndCapture(hub, error, event, 'onerror');
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** JSDoc */
|
||||
function _installGlobalOnUnhandledRejectionHandler() {
|
||||
addInstrumentationHandler(
|
||||
'unhandledrejection',
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(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 (shouldIgnoreOnError() || (error && error.__sentry_own_request__)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const event = isPrimitive(error)
|
||||
? _eventFromRejectionWithPrimitive(error)
|
||||
: 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.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function _eventFromIncompleteOnError(msg, url, line, column) {
|
||||
const 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 = isErrorEvent(msg) ? msg.message : msg;
|
||||
let name = 'Error';
|
||||
|
||||
const groups = message.match(ERROR_TYPES_RE);
|
||||
if (groups) {
|
||||
name = groups[1];
|
||||
message = groups[2];
|
||||
}
|
||||
|
||||
const event = {
|
||||
exception: {
|
||||
values: [
|
||||
{
|
||||
type: name,
|
||||
value: message,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
return _enhanceEventWithInitialFrame(event, url, line, column);
|
||||
}
|
||||
|
||||
/** JSDoc */
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function _enhanceEventWithInitialFrame(event, url, line, column) {
|
||||
// event.exception
|
||||
const e = (event.exception = event.exception || {});
|
||||
// event.exception.values
|
||||
const ev = (e.values = e.values || []);
|
||||
// event.exception.values[0]
|
||||
const ev0 = (ev[0] = ev[0] || {});
|
||||
// event.exception.values[0].stacktrace
|
||||
const ev0s = (ev0.stacktrace = ev0.stacktrace || {});
|
||||
// event.exception.values[0].stacktrace.frames
|
||||
const ev0sf = (ev0s.frames = ev0s.frames || []);
|
||||
|
||||
const colno = isNaN(parseInt(column, 10)) ? undefined : column;
|
||||
const lineno = isNaN(parseInt(line, 10)) ? undefined : line;
|
||||
const filename = isString(url) && url.length > 0 ? url : 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) {
|
||||
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log(`Global Handler attached: ${type}`);
|
||||
}
|
||||
|
||||
function addMechanismAndCapture(hub, error, event, type) {
|
||||
addExceptionMechanism(event, {
|
||||
handled: false,
|
||||
type,
|
||||
});
|
||||
hub.captureEvent(event, {
|
||||
originalException: error,
|
||||
});
|
||||
}
|
||||
|
||||
function getHubAndOptions() {
|
||||
const hub = getCurrentHub();
|
||||
const client = hub.getClient();
|
||||
const options = (client && client.getOptions()) || {
|
||||
stackParser: () => [],
|
||||
attachStacktrace: false,
|
||||
};
|
||||
return [hub, options.stackParser, options.attachStacktrace];
|
||||
}
|
||||
|
||||
export { GlobalHandlers };
|
||||
//# sourceMappingURL=globalhandlers.js.map
|
||||
47
shared/logger/node_modules/@sentry/browser/esm/integrations/httpcontext.js
generated
vendored
Normal file
47
shared/logger/node_modules/@sentry/browser/esm/integrations/httpcontext.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import { addGlobalEventProcessor, getCurrentHub } from '@sentry/core';
|
||||
import { WINDOW } from '../helpers.js';
|
||||
|
||||
/** HttpContext integration collects information about HTTP request headers */
|
||||
class HttpContext {constructor() { HttpContext.prototype.__init.call(this); }
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
static __initStatic() {this.id = 'HttpContext';}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
__init() {this.name = HttpContext.id;}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
setupOnce() {
|
||||
addGlobalEventProcessor((event) => {
|
||||
if (getCurrentHub().getIntegration(HttpContext)) {
|
||||
// if none of the information we want exists, don't bother
|
||||
if (!WINDOW.navigator && !WINDOW.location && !WINDOW.document) {
|
||||
return event;
|
||||
}
|
||||
|
||||
// grab as much info as exists and add it to the event
|
||||
const url = (event.request && event.request.url) || (WINDOW.location && WINDOW.location.href);
|
||||
const { referrer } = WINDOW.document || {};
|
||||
const { userAgent } = WINDOW.navigator || {};
|
||||
|
||||
const headers = {
|
||||
...(event.request && event.request.headers),
|
||||
...(referrer && { Referer: referrer }),
|
||||
...(userAgent && { 'User-Agent': userAgent }),
|
||||
};
|
||||
const request = { ...event.request, ...(url && { url }), headers };
|
||||
|
||||
return { ...event, request };
|
||||
}
|
||||
return event;
|
||||
});
|
||||
}
|
||||
} HttpContext.__initStatic();
|
||||
|
||||
export { HttpContext };
|
||||
//# sourceMappingURL=httpcontext.js.map
|
||||
87
shared/logger/node_modules/@sentry/browser/esm/integrations/linkederrors.js
generated
vendored
Normal file
87
shared/logger/node_modules/@sentry/browser/esm/integrations/linkederrors.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
import { getCurrentHub, addGlobalEventProcessor } from '@sentry/core';
|
||||
import { isInstanceOf } from '@sentry/utils';
|
||||
import { exceptionFromError } from '../eventbuilder.js';
|
||||
|
||||
const DEFAULT_KEY = 'cause';
|
||||
const DEFAULT_LIMIT = 5;
|
||||
|
||||
/** Adds SDK info to an event. */
|
||||
class LinkedErrors {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
static __initStatic() {this.id = 'LinkedErrors';}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
__init() {this.name = LinkedErrors.id;}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
constructor(options = {}) {LinkedErrors.prototype.__init.call(this);
|
||||
this._key = options.key || DEFAULT_KEY;
|
||||
this._limit = options.limit || DEFAULT_LIMIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
setupOnce() {
|
||||
const client = getCurrentHub().getClient();
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
addGlobalEventProcessor((event, hint) => {
|
||||
const self = getCurrentHub().getIntegration(LinkedErrors);
|
||||
return self ? _handler(client.getOptions().stackParser, self._key, self._limit, event, hint) : event;
|
||||
});
|
||||
}
|
||||
} LinkedErrors.__initStatic();
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
function _handler(
|
||||
parser,
|
||||
key,
|
||||
limit,
|
||||
event,
|
||||
hint,
|
||||
) {
|
||||
if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) {
|
||||
return event;
|
||||
}
|
||||
const linkedErrors = _walkErrorTree(parser, limit, hint.originalException , key);
|
||||
event.exception.values = [...linkedErrors, ...event.exception.values];
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* JSDOC
|
||||
*/
|
||||
function _walkErrorTree(
|
||||
parser,
|
||||
limit,
|
||||
error,
|
||||
key,
|
||||
stack = [],
|
||||
) {
|
||||
if (!isInstanceOf(error[key], Error) || stack.length + 1 >= limit) {
|
||||
return stack;
|
||||
}
|
||||
const exception = exceptionFromError(parser, error[key]);
|
||||
return _walkErrorTree(parser, limit, error[key], key, [exception, ...stack]);
|
||||
}
|
||||
|
||||
export { LinkedErrors, _handler, _walkErrorTree };
|
||||
//# sourceMappingURL=linkederrors.js.map
|
||||
281
shared/logger/node_modules/@sentry/browser/esm/integrations/trycatch.js
generated
vendored
Normal file
281
shared/logger/node_modules/@sentry/browser/esm/integrations/trycatch.js
generated
vendored
Normal file
@@ -0,0 +1,281 @@
|
||||
import { fill, getFunctionName, getOriginalFunction } from '@sentry/utils';
|
||||
import { WINDOW, wrap } from '../helpers.js';
|
||||
|
||||
const DEFAULT_EVENT_TARGET = [
|
||||
'EventTarget',
|
||||
'Window',
|
||||
'Node',
|
||||
'ApplicationCache',
|
||||
'AudioTrackList',
|
||||
'ChannelMergerNode',
|
||||
'CryptoOperation',
|
||||
'EventSource',
|
||||
'FileReader',
|
||||
'HTMLUnknownElement',
|
||||
'IDBDatabase',
|
||||
'IDBRequest',
|
||||
'IDBTransaction',
|
||||
'KeyOperation',
|
||||
'MediaController',
|
||||
'MessagePort',
|
||||
'ModalWindow',
|
||||
'Notification',
|
||||
'SVGElementInstance',
|
||||
'Screen',
|
||||
'TextTrack',
|
||||
'TextTrackCue',
|
||||
'TextTrackList',
|
||||
'WebSocket',
|
||||
'WebSocketWorker',
|
||||
'Worker',
|
||||
'XMLHttpRequest',
|
||||
'XMLHttpRequestEventTarget',
|
||||
'XMLHttpRequestUpload',
|
||||
];
|
||||
|
||||
/** Wrap timer functions and event targets to catch errors and provide better meta data */
|
||||
class TryCatch {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
static __initStatic() {this.id = 'TryCatch';}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
__init() {this.name = TryCatch.id;}
|
||||
|
||||
/** JSDoc */
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
constructor(options) {TryCatch.prototype.__init.call(this);
|
||||
this._options = {
|
||||
XMLHttpRequest: true,
|
||||
eventTarget: true,
|
||||
requestAnimationFrame: true,
|
||||
setInterval: true,
|
||||
setTimeout: true,
|
||||
...options,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap timer functions and event targets to catch errors
|
||||
* and provide better metadata.
|
||||
*/
|
||||
setupOnce() {
|
||||
if (this._options.setTimeout) {
|
||||
fill(WINDOW, 'setTimeout', _wrapTimeFunction);
|
||||
}
|
||||
|
||||
if (this._options.setInterval) {
|
||||
fill(WINDOW, 'setInterval', _wrapTimeFunction);
|
||||
}
|
||||
|
||||
if (this._options.requestAnimationFrame) {
|
||||
fill(WINDOW, 'requestAnimationFrame', _wrapRAF);
|
||||
}
|
||||
|
||||
if (this._options.XMLHttpRequest && 'XMLHttpRequest' in WINDOW) {
|
||||
fill(XMLHttpRequest.prototype, 'send', _wrapXHR);
|
||||
}
|
||||
|
||||
const eventTargetOption = this._options.eventTarget;
|
||||
if (eventTargetOption) {
|
||||
const eventTarget = Array.isArray(eventTargetOption) ? eventTargetOption : DEFAULT_EVENT_TARGET;
|
||||
eventTarget.forEach(_wrapEventTarget);
|
||||
}
|
||||
}
|
||||
} TryCatch.__initStatic();
|
||||
|
||||
/** JSDoc */
|
||||
function _wrapTimeFunction(original) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return function ( ...args) {
|
||||
const originalCallback = args[0];
|
||||
args[0] = wrap(originalCallback, {
|
||||
mechanism: {
|
||||
data: { function: getFunctionName(original) },
|
||||
handled: true,
|
||||
type: 'instrument',
|
||||
},
|
||||
});
|
||||
return original.apply(this, args);
|
||||
};
|
||||
}
|
||||
|
||||
/** JSDoc */
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function _wrapRAF(original) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return function ( callback) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
return original.apply(this, [
|
||||
wrap(callback, {
|
||||
mechanism: {
|
||||
data: {
|
||||
function: 'requestAnimationFrame',
|
||||
handler: getFunctionName(original),
|
||||
},
|
||||
handled: true,
|
||||
type: 'instrument',
|
||||
},
|
||||
}),
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
/** JSDoc */
|
||||
function _wrapXHR(originalSend) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return function ( ...args) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
const xhr = this;
|
||||
const xmlHttpRequestProps = ['onload', 'onerror', 'onprogress', 'onreadystatechange'];
|
||||
|
||||
xmlHttpRequestProps.forEach(prop => {
|
||||
if (prop in xhr && typeof xhr[prop] === 'function') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
fill(xhr, prop, function (original) {
|
||||
const wrapOptions = {
|
||||
mechanism: {
|
||||
data: {
|
||||
function: prop,
|
||||
handler: getFunctionName(original),
|
||||
},
|
||||
handled: true,
|
||||
type: 'instrument',
|
||||
},
|
||||
};
|
||||
|
||||
// If Instrument integration has been called before TryCatch, get the name of original function
|
||||
const originalFunction = getOriginalFunction(original);
|
||||
if (originalFunction) {
|
||||
wrapOptions.mechanism.data.handler = getFunctionName(originalFunction);
|
||||
}
|
||||
|
||||
// Otherwise wrap directly
|
||||
return wrap(original, wrapOptions);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return originalSend.apply(this, args);
|
||||
};
|
||||
}
|
||||
|
||||
/** JSDoc */
|
||||
function _wrapEventTarget(target) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const globalObject = WINDOW ;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
const proto = globalObject[target] && globalObject[target].prototype;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins
|
||||
if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
|
||||
return;
|
||||
}
|
||||
|
||||
fill(proto, 'addEventListener', function (original)
|
||||
|
||||
{
|
||||
return function (
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
eventName,
|
||||
fn,
|
||||
options,
|
||||
) {
|
||||
try {
|
||||
if (typeof fn.handleEvent === 'function') {
|
||||
// ESlint disable explanation:
|
||||
// First, it is generally safe to call `wrap` with an unbound function. Furthermore, using `.bind()` would
|
||||
// introduce a bug here, because bind returns a new function that doesn't have our
|
||||
// flags(like __sentry_original__) attached. `wrap` checks for those flags to avoid unnecessary wrapping.
|
||||
// Without those flags, every call to addEventListener wraps the function again, causing a memory leak.
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
fn.handleEvent = wrap(fn.handleEvent, {
|
||||
mechanism: {
|
||||
data: {
|
||||
function: 'handleEvent',
|
||||
handler: getFunctionName(fn),
|
||||
target,
|
||||
},
|
||||
handled: true,
|
||||
type: 'instrument',
|
||||
},
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
// can sometimes get 'Permission denied to access property "handle Event'
|
||||
}
|
||||
|
||||
return original.apply(this, [
|
||||
eventName,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
wrap(fn , {
|
||||
mechanism: {
|
||||
data: {
|
||||
function: 'addEventListener',
|
||||
handler: getFunctionName(fn),
|
||||
target,
|
||||
},
|
||||
handled: true,
|
||||
type: 'instrument',
|
||||
},
|
||||
}),
|
||||
options,
|
||||
]);
|
||||
};
|
||||
});
|
||||
|
||||
fill(
|
||||
proto,
|
||||
'removeEventListener',
|
||||
function (
|
||||
originalRemoveEventListener,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
) {
|
||||
return function (
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
eventName,
|
||||
fn,
|
||||
options,
|
||||
) {
|
||||
/**
|
||||
* There are 2 possible scenarios here:
|
||||
*
|
||||
* 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified
|
||||
* method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function
|
||||
* as a pass-through, and call original `removeEventListener` with it.
|
||||
*
|
||||
* 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using
|
||||
* our wrapped version of `addEventListener`, which internally calls `wrap` helper.
|
||||
* This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it,
|
||||
* in order for us to make a distinction between wrapped/non-wrapped functions possible.
|
||||
* If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.
|
||||
*
|
||||
* When someone adds a handler prior to initialization, and then do it again, but after,
|
||||
* then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible
|
||||
* to get rid of the initial handler and it'd stick there forever.
|
||||
*/
|
||||
const wrappedEventHandler = fn ;
|
||||
try {
|
||||
const originalEventHandler = wrappedEventHandler && wrappedEventHandler.__sentry_wrapped__;
|
||||
if (originalEventHandler) {
|
||||
originalRemoveEventListener.call(this, eventName, originalEventHandler, options);
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore, accessing __sentry_wrapped__ will throw in some Selenium environments
|
||||
}
|
||||
return originalRemoveEventListener.call(this, eventName, wrappedEventHandler, options);
|
||||
};
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export { TryCatch };
|
||||
//# sourceMappingURL=trycatch.js.map
|
||||
Reference in New Issue
Block a user