1 | import { isError, normalize, isPlainObject, addNonEnumerableProperty, logger } from '@sentry/utils';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | class ExtraErrorData {
|
7 | |
8 |
|
9 |
|
10 | static __initStatic() {this.id = 'ExtraErrorData';}
|
11 |
|
12 | |
13 |
|
14 |
|
15 | __init() {this.name = ExtraErrorData.id;}
|
16 |
|
17 |
|
18 |
|
19 | |
20 |
|
21 |
|
22 | constructor(options) {ExtraErrorData.prototype.__init.call(this);
|
23 | this._options = {
|
24 | depth: 3,
|
25 | ...options,
|
26 | };
|
27 | }
|
28 |
|
29 | |
30 |
|
31 |
|
32 | setupOnce(addGlobalEventProcessor, getCurrentHub) {
|
33 | addGlobalEventProcessor((event, hint) => {
|
34 | const self = getCurrentHub().getIntegration(ExtraErrorData);
|
35 | if (!self) {
|
36 | return event;
|
37 | }
|
38 | return self.enhanceEventWithErrorData(event, hint);
|
39 | });
|
40 | }
|
41 |
|
42 | |
43 |
|
44 |
|
45 | enhanceEventWithErrorData(event, hint = {}) {
|
46 | if (!hint.originalException || !isError(hint.originalException)) {
|
47 | return event;
|
48 | }
|
49 | const exceptionName = (hint.originalException ).name || hint.originalException.constructor.name;
|
50 |
|
51 | const errorData = this._extractErrorData(hint.originalException );
|
52 |
|
53 | if (errorData) {
|
54 | const contexts = {
|
55 | ...event.contexts,
|
56 | };
|
57 |
|
58 | const normalizedErrorData = normalize(errorData, this._options.depth);
|
59 |
|
60 | if (isPlainObject(normalizedErrorData)) {
|
61 |
|
62 |
|
63 | addNonEnumerableProperty(normalizedErrorData, '__sentry_skip_normalization__', true);
|
64 | contexts[exceptionName] = normalizedErrorData;
|
65 | }
|
66 |
|
67 | return {
|
68 | ...event,
|
69 | contexts,
|
70 | };
|
71 | }
|
72 |
|
73 | return event;
|
74 | }
|
75 |
|
76 | |
77 |
|
78 |
|
79 | _extractErrorData(error) {
|
80 |
|
81 | try {
|
82 | const nativeKeys = [
|
83 | 'name',
|
84 | 'message',
|
85 | 'stack',
|
86 | 'line',
|
87 | 'column',
|
88 | 'fileName',
|
89 | 'lineNumber',
|
90 | 'columnNumber',
|
91 | 'toJSON',
|
92 | ];
|
93 |
|
94 | const extraErrorInfo = {};
|
95 |
|
96 |
|
97 | for (const key of Object.keys(error)) {
|
98 | if (nativeKeys.indexOf(key) !== -1) {
|
99 | continue;
|
100 | }
|
101 | const value = error[key];
|
102 | extraErrorInfo[key] = isError(value) ? value.toString() : value;
|
103 | }
|
104 |
|
105 |
|
106 | if (typeof error.toJSON === 'function') {
|
107 | const serializedError = error.toJSON() ;
|
108 |
|
109 | for (const key of Object.keys(serializedError)) {
|
110 | const value = serializedError[key];
|
111 | extraErrorInfo[key] = isError(value) ? value.toString() : value;
|
112 | }
|
113 | }
|
114 |
|
115 | return extraErrorInfo;
|
116 | } catch (oO) {
|
117 | (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error('Unable to extract extra data from the Error object:', oO);
|
118 | }
|
119 |
|
120 | return null;
|
121 | }
|
122 | } ExtraErrorData.__initStatic();
|
123 |
|
124 | export { ExtraErrorData };
|
125 |
|