summaryrefslogtreecommitdiff
path: root/shared/logger/node_modules/@sentry/browser/esm/eventbuilder.js
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /shared/logger/node_modules/@sentry/browser/esm/eventbuilder.js
init commit
Diffstat (limited to 'shared/logger/node_modules/@sentry/browser/esm/eventbuilder.js')
-rw-r--r--shared/logger/node_modules/@sentry/browser/esm/eventbuilder.js304
1 files changed, 304 insertions, 0 deletions
diff --git a/shared/logger/node_modules/@sentry/browser/esm/eventbuilder.js b/shared/logger/node_modules/@sentry/browser/esm/eventbuilder.js
new file mode 100644
index 0000000..08e5653
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/browser/esm/eventbuilder.js
@@ -0,0 +1,304 @@
+import { getCurrentHub } from '@sentry/core';
+import { addExceptionMechanism, resolvedSyncPromise, isErrorEvent, isDOMError, isDOMException, addExceptionTypeValue, isError, isPlainObject, isEvent, normalizeToSize, extractExceptionKeysForMessage } from '@sentry/utils';
+
+/**
+ * This function creates an exception from a JavaScript Error
+ */
+function exceptionFromError(stackParser, ex) {
+ // Get the frames first since Opera can lose the stack if we touch anything else first
+ const frames = parseStackFrames(stackParser, ex);
+
+ const exception = {
+ type: ex && ex.name,
+ value: extractMessage(ex),
+ };
+
+ if (frames.length) {
+ exception.stacktrace = { frames };
+ }
+
+ if (exception.type === undefined && exception.value === '') {
+ exception.value = 'Unrecoverable error caught';
+ }
+
+ return exception;
+}
+
+/**
+ * @hidden
+ */
+function eventFromPlainObject(
+ stackParser,
+ exception,
+ syntheticException,
+ isUnhandledRejection,
+) {
+ const hub = getCurrentHub();
+ const client = hub.getClient();
+ const normalizeDepth = client && client.getOptions().normalizeDepth;
+
+ const event = {
+ exception: {
+ values: [
+ {
+ type: isEvent(exception) ? exception.constructor.name : isUnhandledRejection ? 'UnhandledRejection' : 'Error',
+ value: getNonErrorObjectExceptionValue(exception, { isUnhandledRejection }),
+ },
+ ],
+ },
+ extra: {
+ __serialized__: normalizeToSize(exception, normalizeDepth),
+ },
+ };
+
+ if (syntheticException) {
+ const frames = parseStackFrames(stackParser, syntheticException);
+ if (frames.length) {
+ // event.exception.values[0] has been set above
+ (event.exception ).values[0].stacktrace = { frames };
+ }
+ }
+
+ return event;
+}
+
+/**
+ * @hidden
+ */
+function eventFromError(stackParser, ex) {
+ return {
+ exception: {
+ values: [exceptionFromError(stackParser, ex)],
+ },
+ };
+}
+
+/** Parses stack frames from an error */
+function parseStackFrames(
+ stackParser,
+ ex,
+) {
+ // Access and store the stacktrace property before doing ANYTHING
+ // else to it because Opera is not very good at providing it
+ // reliably in other circumstances.
+ const stacktrace = ex.stacktrace || ex.stack || '';
+
+ const popSize = getPopSize(ex);
+
+ try {
+ return stackParser(stacktrace, popSize);
+ } catch (e) {
+ // no-empty
+ }
+
+ return [];
+}
+
+// Based on our own mapping pattern - https://github.com/getsentry/sentry/blob/9f08305e09866c8bd6d0c24f5b0aabdd7dd6c59c/src/sentry/lang/javascript/errormapping.py#L83-L108
+const reactMinifiedRegexp = /Minified React error #\d+;/i;
+
+function getPopSize(ex) {
+ if (ex) {
+ if (typeof ex.framesToPop === 'number') {
+ return ex.framesToPop;
+ }
+
+ if (reactMinifiedRegexp.test(ex.message)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * There are cases where stacktrace.message is an Event object
+ * https://github.com/getsentry/sentry-javascript/issues/1949
+ * In this specific case we try to extract stacktrace.message.error.message
+ */
+function extractMessage(ex) {
+ const message = ex && ex.message;
+ if (!message) {
+ return 'No error message';
+ }
+ if (message.error && typeof message.error.message === 'string') {
+ return message.error.message;
+ }
+ return message;
+}
+
+/**
+ * Creates an {@link Event} from all inputs to `captureException` and non-primitive inputs to `captureMessage`.
+ * @hidden
+ */
+function eventFromException(
+ stackParser,
+ exception,
+ hint,
+ attachStacktrace,
+) {
+ const syntheticException = (hint && hint.syntheticException) || undefined;
+ const event = eventFromUnknownInput(stackParser, exception, syntheticException, attachStacktrace);
+ addExceptionMechanism(event); // defaults to { type: 'generic', handled: true }
+ event.level = 'error';
+ if (hint && hint.event_id) {
+ event.event_id = hint.event_id;
+ }
+ return resolvedSyncPromise(event);
+}
+
+/**
+ * Builds and Event from a Message
+ * @hidden
+ */
+function eventFromMessage(
+ stackParser,
+ message,
+ // eslint-disable-next-line deprecation/deprecation
+ level = 'info',
+ hint,
+ attachStacktrace,
+) {
+ const syntheticException = (hint && hint.syntheticException) || undefined;
+ const event = eventFromString(stackParser, message, syntheticException, attachStacktrace);
+ event.level = level;
+ if (hint && hint.event_id) {
+ event.event_id = hint.event_id;
+ }
+ return resolvedSyncPromise(event);
+}
+
+/**
+ * @hidden
+ */
+function eventFromUnknownInput(
+ stackParser,
+ exception,
+ syntheticException,
+ attachStacktrace,
+ isUnhandledRejection,
+) {
+ let event;
+
+ if (isErrorEvent(exception ) && (exception ).error) {
+ // If it is an ErrorEvent with `error` property, extract it to get actual Error
+ const errorEvent = exception ;
+ return eventFromError(stackParser, errorEvent.error );
+ }
+
+ // If it is a `DOMError` (which is a legacy API, but still supported in some browsers) then we just extract the name
+ // and message, as it doesn't provide anything else. According to the spec, all `DOMExceptions` should also be
+ // `Error`s, but that's not the case in IE11, so in that case we treat it the same as we do a `DOMError`.
+ //
+ // https://developer.mozilla.org/en-US/docs/Web/API/DOMError
+ // https://developer.mozilla.org/en-US/docs/Web/API/DOMException
+ // https://webidl.spec.whatwg.org/#es-DOMException-specialness
+ if (isDOMError(exception) || isDOMException(exception )) {
+ const domException = exception ;
+
+ if ('stack' in (exception )) {
+ event = eventFromError(stackParser, exception );
+ } 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) {
+ // eslint-disable-next-line deprecation/deprecation
+ event.tags = { ...event.tags, 'DOMException.code': `${domException.code}` };
+ }
+
+ return event;
+ }
+ if (isError(exception)) {
+ // we have a real Error object, do nothing
+ return eventFromError(stackParser, exception);
+ }
+ if (isPlainObject(exception) || isEvent(exception)) {
+ // If it's a plain object or an instance of `Event` (the built-in JS kind, not this SDK's `Event` type), serialize
+ // it manually. This will allow us to group events based on top-level keys which is much better than creating a new
+ // group on any key/value change.
+ const objectException = exception ;
+ event = eventFromPlainObject(stackParser, objectException, syntheticException, isUnhandledRejection);
+ addExceptionMechanism(event, {
+ synthetic: true,
+ });
+ return event;
+ }
+
+ // If none of previous checks were valid, then it means that it's not:
+ // - an instance of DOMError
+ // - an instance of DOMException
+ // - an instance of Event
+ // - an instance of Error
+ // - a valid ErrorEvent (one with an error property)
+ // - a plain Object
+ //
+ // So bail out and capture it as a simple message:
+ event = eventFromString(stackParser, exception , syntheticException, attachStacktrace);
+ addExceptionTypeValue(event, `${exception}`, undefined);
+ addExceptionMechanism(event, {
+ synthetic: true,
+ });
+
+ return event;
+}
+
+/**
+ * @hidden
+ */
+function eventFromString(
+ stackParser,
+ input,
+ syntheticException,
+ attachStacktrace,
+) {
+ const event = {
+ message: input,
+ };
+
+ if (attachStacktrace && syntheticException) {
+ const frames = parseStackFrames(stackParser, syntheticException);
+ if (frames.length) {
+ event.exception = {
+ values: [{ value: input, stacktrace: { frames } }],
+ };
+ }
+ }
+
+ return event;
+}
+
+function getNonErrorObjectExceptionValue(
+ exception,
+ { isUnhandledRejection },
+) {
+ const keys = extractExceptionKeysForMessage(exception);
+ const captureType = isUnhandledRejection ? 'promise rejection' : 'exception';
+
+ // Some ErrorEvent instances do not have an `error` property, which is why they are not handled before
+ // We still want to try to get a decent message for these cases
+ 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 : undefined;
+ } catch (e) {
+ // ignore errors here
+ }
+}
+
+export { eventFromError, eventFromException, eventFromMessage, eventFromPlainObject, eventFromString, eventFromUnknownInput, exceptionFromError, parseStackFrames };
+//# sourceMappingURL=eventbuilder.js.map