@sentry/browser
Version:
Official Sentry SDK for browsers
225 lines (222 loc) • 7.88 kB
JavaScript
import { isErrorEvent, isDOMError, isDOMException, addExceptionTypeValue, isError, isPlainObject, isEvent, addExceptionMechanism, isParameterizedString, getClient, normalizeToSize, extractExceptionKeysForMessage, _INTERNAL_enhanceErrorWithSentryInfo, resolvedSyncPromise } from '@sentry/core/browser';
function exceptionFromError(stackParser, ex) {
const frames = parseStackFrames(stackParser, ex);
const exception = {
type: extractType(ex),
value: extractMessage(ex)
};
if (frames.length) {
exception.stacktrace = { frames };
}
if (exception.type === void 0 && exception.value === "") {
exception.value = "Unrecoverable error caught";
}
return exception;
}
function eventFromPlainObject(stackParser, exception, syntheticException, isUnhandledRejection) {
const client = getClient();
const normalizeDepth = client?.getOptions().normalizeDepth;
const errorFromProp = getErrorPropertyFromObject(exception);
const extra = {
__serialized__: normalizeToSize(exception, normalizeDepth)
};
if (errorFromProp) {
return {
exception: {
values: [exceptionFromError(stackParser, errorFromProp)]
},
extra
};
}
const event = {
exception: {
values: [
{
type: isEvent(exception) ? exception.constructor.name : isUnhandledRejection ? "UnhandledRejection" : "Error",
value: getNonErrorObjectExceptionValue(exception, { isUnhandledRejection })
}
]
},
extra
};
if (syntheticException) {
const frames = parseStackFrames(stackParser, syntheticException);
if (frames.length) {
event.exception.values[0].stacktrace = { frames };
}
}
return event;
}
function eventFromError(stackParser, ex) {
return {
exception: {
values: [exceptionFromError(stackParser, ex)]
}
};
}
function parseStackFrames(stackParser, ex) {
const stacktrace = ex.stacktrace || ex.stack || "";
const skipLines = getSkipFirstStackStringLines(ex);
const framesToPop = getPopFirstTopFrames(ex);
try {
return stackParser(stacktrace, skipLines, framesToPop);
} catch {
}
return [];
}
const reactMinifiedRegexp = /Minified React error #\d+;/i;
function getSkipFirstStackStringLines(ex) {
if (ex && reactMinifiedRegexp.test(ex.message)) {
return 1;
}
return 0;
}
function getPopFirstTopFrames(ex) {
if (typeof ex.framesToPop === "number") {
return ex.framesToPop;
}
return 0;
}
function isWebAssemblyException(exception) {
if (typeof WebAssembly !== "undefined" && typeof WebAssembly.Exception !== "undefined") {
return exception instanceof WebAssembly.Exception;
} else {
return false;
}
}
function extractType(ex) {
const name = ex?.name;
if (!name && isWebAssemblyException(ex)) {
const hasTypeInMessage = ex.message && Array.isArray(ex.message) && ex.message.length == 2;
return hasTypeInMessage ? ex.message[0] : "WebAssembly.Exception";
}
return name;
}
function extractMessage(ex) {
const message = ex?.message;
if (isWebAssemblyException(ex)) {
if (Array.isArray(ex.message) && ex.message.length == 2) {
return ex.message[1];
}
return "wasm exception";
}
if (!message) {
return "No error message";
}
if (message.error && typeof message.error.message === "string") {
return _INTERNAL_enhanceErrorWithSentryInfo(message.error);
}
return _INTERNAL_enhanceErrorWithSentryInfo(ex);
}
function eventFromException(stackParser, exception, hint, attachStacktrace) {
const syntheticException = hint?.syntheticException || void 0;
const event = eventFromUnknownInput(stackParser, exception, syntheticException, attachStacktrace);
addExceptionMechanism(event);
event.level = "error";
if (hint?.event_id) {
event.event_id = hint.event_id;
}
return resolvedSyncPromise(event);
}
function eventFromMessage(stackParser, message, level = "info", hint, attachStacktrace) {
const syntheticException = hint?.syntheticException || void 0;
const event = eventFromString(stackParser, message, syntheticException, attachStacktrace);
event.level = level;
if (hint?.event_id) {
event.event_id = hint.event_id;
}
return resolvedSyncPromise(event);
}
function eventFromUnknownInput(stackParser, exception, syntheticException, attachStacktrace, isUnhandledRejection) {
let event;
if (isErrorEvent(exception) && exception.error) {
const errorEvent = exception;
return eventFromError(stackParser, errorEvent.error);
}
if (isDOMError(exception) || isDOMException(exception)) {
const domException = exception;
if ("stack" in exception) {
event = eventFromError(stackParser, exception);
const firstException = event.exception?.values?.[0];
if (attachStacktrace && syntheticException && firstException && !firstException.stacktrace) {
const frames = parseStackFrames(stackParser, syntheticException);
if (frames.length) {
firstException.stacktrace = { frames };
addExceptionMechanism(event, { synthetic: true });
}
}
} else {
const name = domException.name || (isDOMError(domException) ? "DOMError" : "DOMException");
const message = domException.message ? `${name}: ${domException.message}` : name;
event = eventFromString(stackParser, message, syntheticException, attachStacktrace);
addExceptionTypeValue(event, message);
}
if ("code" in domException) {
event.tags = { ...event.tags, "DOMException.code": `${domException.code}` };
}
return event;
}
if (isError(exception)) {
return eventFromError(stackParser, exception);
}
if (isPlainObject(exception) || isEvent(exception)) {
const objectException = exception;
event = eventFromPlainObject(stackParser, objectException, syntheticException, isUnhandledRejection);
addExceptionMechanism(event, {
synthetic: true
});
return event;
}
event = eventFromString(stackParser, exception, syntheticException, attachStacktrace);
addExceptionTypeValue(event, `${exception}`, void 0);
addExceptionMechanism(event, {
synthetic: true
});
return event;
}
function eventFromString(stackParser, message, syntheticException, attachStacktrace) {
const event = {};
if (attachStacktrace && syntheticException) {
const frames = parseStackFrames(stackParser, syntheticException);
if (frames.length) {
event.exception = {
values: [{ value: message, stacktrace: { frames } }]
};
}
addExceptionMechanism(event, { synthetic: true });
}
if (isParameterizedString(message)) {
const { __sentry_template_string__, __sentry_template_values__ } = message;
event.logentry = {
message: __sentry_template_string__,
params: __sentry_template_values__
};
return event;
}
event.message = message;
return event;
}
function getNonErrorObjectExceptionValue(exception, { isUnhandledRejection }) {
const keys = extractExceptionKeysForMessage(exception);
const captureType = isUnhandledRejection ? "promise rejection" : "exception";
if (isErrorEvent(exception)) {
return `Event \`ErrorEvent\` captured as ${captureType} with message \`${exception.message}\``;
}
if (isEvent(exception)) {
const className = getObjectClassName(exception);
return `Event \`${className}\` (type=${exception.type}) captured as ${captureType}`;
}
return `Object captured as ${captureType} with keys: ${keys}`;
}
function getObjectClassName(obj) {
try {
const prototype = Object.getPrototypeOf(obj);
return prototype ? prototype.constructor.name : void 0;
} catch {
}
}
function getErrorPropertyFromObject(obj) {
return Object.values(obj).find((v) => v instanceof Error);
}
export { eventFromException, eventFromMessage, eventFromUnknownInput, exceptionFromError, extractMessage, extractType };
//# sourceMappingURL=eventbuilder.js.map