UNPKG

8.45 kBJavaScriptView Raw
1Object.defineProperty(exports, "__esModule", { value: true });
2var tslib_1 = require("tslib");
3var types_1 = require("@sentry/types");
4var utils_1 = require("@sentry/utils");
5var stack_parsers_1 = require("./stack-parsers");
6/**
7 * This function creates an exception from an TraceKitStackTrace
8 * @param stacktrace TraceKitStackTrace that will be converted to an exception
9 * @hidden
10 */
11function exceptionFromError(ex) {
12 // Get the frames first since Opera can lose the stack if we touch anything else first
13 var frames = parseStackFrames(ex);
14 var exception = {
15 type: ex && ex.name,
16 value: extractMessage(ex),
17 };
18 if (frames.length) {
19 exception.stacktrace = { frames: frames };
20 }
21 if (exception.type === undefined && exception.value === '') {
22 exception.value = 'Unrecoverable error caught';
23 }
24 return exception;
25}
26exports.exceptionFromError = exceptionFromError;
27/**
28 * @hidden
29 */
30function eventFromPlainObject(exception, syntheticException, isUnhandledRejection) {
31 var event = {
32 exception: {
33 values: [
34 {
35 type: utils_1.isEvent(exception) ? exception.constructor.name : isUnhandledRejection ? 'UnhandledRejection' : 'Error',
36 value: "Non-Error " + (isUnhandledRejection ? 'promise rejection' : 'exception') + " captured with keys: " + utils_1.extractExceptionKeysForMessage(exception),
37 },
38 ],
39 },
40 extra: {
41 __serialized__: utils_1.normalizeToSize(exception),
42 },
43 };
44 if (syntheticException) {
45 var frames_1 = parseStackFrames(syntheticException);
46 if (frames_1.length) {
47 event.stacktrace = { frames: frames_1 };
48 }
49 }
50 return event;
51}
52exports.eventFromPlainObject = eventFromPlainObject;
53/**
54 * @hidden
55 */
56function eventFromError(ex) {
57 return {
58 exception: {
59 values: [exceptionFromError(ex)],
60 },
61 };
62}
63exports.eventFromError = eventFromError;
64/** Parses stack frames from an error */
65function parseStackFrames(ex) {
66 // Access and store the stacktrace property before doing ANYTHING
67 // else to it because Opera is not very good at providing it
68 // reliably in other circumstances.
69 var stacktrace = ex.stacktrace || ex.stack || '';
70 var popSize = getPopSize(ex);
71 try {
72 return utils_1.createStackParser(stack_parsers_1.opera10StackParser, stack_parsers_1.opera11StackParser, stack_parsers_1.chromeStackParser, stack_parsers_1.winjsStackParser, stack_parsers_1.geckoStackParser)(stacktrace, popSize);
73 }
74 catch (e) {
75 // no-empty
76 }
77 return [];
78}
79exports.parseStackFrames = parseStackFrames;
80// Based on our own mapping pattern - https://github.com/getsentry/sentry/blob/9f08305e09866c8bd6d0c24f5b0aabdd7dd6c59c/src/sentry/lang/javascript/errormapping.py#L83-L108
81var reactMinifiedRegexp = /Minified React error #\d+;/i;
82function getPopSize(ex) {
83 if (ex) {
84 if (typeof ex.framesToPop === 'number') {
85 return ex.framesToPop;
86 }
87 if (reactMinifiedRegexp.test(ex.message)) {
88 return 1;
89 }
90 }
91 return 0;
92}
93/**
94 * There are cases where stacktrace.message is an Event object
95 * https://github.com/getsentry/sentry-javascript/issues/1949
96 * In this specific case we try to extract stacktrace.message.error.message
97 */
98function extractMessage(ex) {
99 var message = ex && ex.message;
100 if (!message) {
101 return 'No error message';
102 }
103 if (message.error && typeof message.error.message === 'string') {
104 return message.error.message;
105 }
106 return message;
107}
108/**
109 * Creates an {@link Event} from all inputs to `captureException` and non-primitive inputs to `captureMessage`.
110 * @hidden
111 */
112function eventFromException(exception, hint, attachStacktrace) {
113 var syntheticException = (hint && hint.syntheticException) || undefined;
114 var event = eventFromUnknownInput(exception, syntheticException, attachStacktrace);
115 utils_1.addExceptionMechanism(event); // defaults to { type: 'generic', handled: true }
116 event.level = types_1.Severity.Error;
117 if (hint && hint.event_id) {
118 event.event_id = hint.event_id;
119 }
120 return utils_1.resolvedSyncPromise(event);
121}
122exports.eventFromException = eventFromException;
123/**
124 * Builds and Event from a Message
125 * @hidden
126 */
127function eventFromMessage(message, level, hint, attachStacktrace) {
128 if (level === void 0) { level = types_1.Severity.Info; }
129 var syntheticException = (hint && hint.syntheticException) || undefined;
130 var event = eventFromString(message, syntheticException, attachStacktrace);
131 event.level = level;
132 if (hint && hint.event_id) {
133 event.event_id = hint.event_id;
134 }
135 return utils_1.resolvedSyncPromise(event);
136}
137exports.eventFromMessage = eventFromMessage;
138/**
139 * @hidden
140 */
141function eventFromUnknownInput(exception, syntheticException, attachStacktrace, isUnhandledRejection) {
142 var event;
143 if (utils_1.isErrorEvent(exception) && exception.error) {
144 // If it is an ErrorEvent with `error` property, extract it to get actual Error
145 var errorEvent = exception;
146 return eventFromError(errorEvent.error);
147 }
148 // If it is a `DOMError` (which is a legacy API, but still supported in some browsers) then we just extract the name
149 // and message, as it doesn't provide anything else. According to the spec, all `DOMExceptions` should also be
150 // `Error`s, but that's not the case in IE11, so in that case we treat it the same as we do a `DOMError`.
151 //
152 // https://developer.mozilla.org/en-US/docs/Web/API/DOMError
153 // https://developer.mozilla.org/en-US/docs/Web/API/DOMException
154 // https://webidl.spec.whatwg.org/#es-DOMException-specialness
155 if (utils_1.isDOMError(exception) || utils_1.isDOMException(exception)) {
156 var domException = exception;
157 if ('stack' in exception) {
158 event = eventFromError(exception);
159 }
160 else {
161 var name_1 = domException.name || (utils_1.isDOMError(domException) ? 'DOMError' : 'DOMException');
162 var message = domException.message ? name_1 + ": " + domException.message : name_1;
163 event = eventFromString(message, syntheticException, attachStacktrace);
164 utils_1.addExceptionTypeValue(event, message);
165 }
166 if ('code' in domException) {
167 event.tags = tslib_1.__assign(tslib_1.__assign({}, event.tags), { 'DOMException.code': "" + domException.code });
168 }
169 return event;
170 }
171 if (utils_1.isError(exception)) {
172 // we have a real Error object, do nothing
173 return eventFromError(exception);
174 }
175 if (utils_1.isPlainObject(exception) || utils_1.isEvent(exception)) {
176 // If it's a plain object or an instance of `Event` (the built-in JS kind, not this SDK's `Event` type), serialize
177 // it manually. This will allow us to group events based on top-level keys which is much better than creating a new
178 // group on any key/value change.
179 var objectException = exception;
180 event = eventFromPlainObject(objectException, syntheticException, isUnhandledRejection);
181 utils_1.addExceptionMechanism(event, {
182 synthetic: true,
183 });
184 return event;
185 }
186 // If none of previous checks were valid, then it means that it's not:
187 // - an instance of DOMError
188 // - an instance of DOMException
189 // - an instance of Event
190 // - an instance of Error
191 // - a valid ErrorEvent (one with an error property)
192 // - a plain Object
193 //
194 // So bail out and capture it as a simple message:
195 event = eventFromString(exception, syntheticException, attachStacktrace);
196 utils_1.addExceptionTypeValue(event, "" + exception, undefined);
197 utils_1.addExceptionMechanism(event, {
198 synthetic: true,
199 });
200 return event;
201}
202exports.eventFromUnknownInput = eventFromUnknownInput;
203/**
204 * @hidden
205 */
206function eventFromString(input, syntheticException, attachStacktrace) {
207 var event = {
208 message: input,
209 };
210 if (attachStacktrace && syntheticException) {
211 var frames_2 = parseStackFrames(syntheticException);
212 if (frames_2.length) {
213 event.stacktrace = { frames: frames_2 };
214 }
215 }
216 return event;
217}
218exports.eventFromString = eventFromString;
219//# sourceMappingURL=eventbuilder.js.map
\No newline at end of file