Skip to content

Commit b476532

Browse files
authored
ref(browser): Simplify TraceKit parser and reorganize tests (#4514)
Refactors and reorganises tracekit unit tests: - Categorize tests per platform/target/framework rather than original/custom - Ensures parse results are tested against the full result object including message and name which were previously not checked - Moved stack strings into individual test so it's easier to visually compare to the output Makes a few simplifications to tracekit parser including: - Remove unused parsed function args - Move address at stripping to the Chrome regex - Remove use in Firefox of `error.columnNumber` since it's not used and even the original tests expect what appears in the stack string
1 parent a547883 commit b476532

File tree

12 files changed

+1577
-2103
lines changed

12 files changed

+1577
-2103
lines changed

packages/browser/src/tracekit.ts

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
export interface StackFrame {
1919
url: string;
2020
func: string;
21-
args: string[];
2221
line: number | null;
2322
column: number | null;
2423
}
@@ -43,7 +42,7 @@ const UNKNOWN_FUNCTION = '?';
4342

4443
// Chromium based browsers: Chrome, Brave, new Opera, new Edge
4544
const chrome =
46-
/^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
45+
/^\s*at (?:(.*?) ?\((?:address at )?)?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
4746
// gecko regex: `(?:bundle|\d+\.js)`: `bundle` is for react native, `\d+\.js` also but specifically for ram bundles because it
4847
// generates filenames without a prefix like `file://` the filenames in the stacktrace are just 42.js
4948
// We need this specific case for now because we want no other regex to match.
@@ -113,9 +112,8 @@ function computeStackTraceFromStackProp(ex: any): StackTrace | null {
113112
let parts;
114113
let element;
115114

116-
for (let i = 0; i < lines.length; ++i) {
117-
if ((parts = chrome.exec(lines[i]))) {
118-
const isNative = parts[2] && parts[2].indexOf('native') === 0; // start of line
115+
for (const line of lines) {
116+
if ((parts = chrome.exec(line))) {
119117
isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line
120118
if (isEval && (submatch = chromeEval.exec(parts[2]))) {
121119
// throw out eval line/column and use top-most line/column number
@@ -124,43 +122,31 @@ function computeStackTraceFromStackProp(ex: any): StackTrace | null {
124122
parts[4] = submatch[3]; // column
125123
}
126124

127-
// Arpad: Working with the regexp above is super painful. it is quite a hack, but just stripping the `address at `
128-
// prefix here seems like the quickest solution for now.
129-
let url = parts[2] && parts[2].indexOf('address at ') === 0 ? parts[2].substr('address at '.length) : parts[2];
130125
// Kamil: One more hack won't hurt us right? Understanding and adding more rules on top of these regexps right now
131126
// would be way too time consuming. (TODO: Rewrite whole RegExp to be more readable)
132-
let func = parts[1] || UNKNOWN_FUNCTION;
133-
[func, url] = extractSafariExtensionDetails(func, url);
127+
const [func, url] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);
134128

135129
element = {
136130
url,
137131
func,
138-
args: isNative ? [parts[2]] : [],
139132
line: parts[3] ? +parts[3] : null,
140133
column: parts[4] ? +parts[4] : null,
141134
};
142-
} else if ((parts = winjs.exec(lines[i]))) {
135+
} else if ((parts = winjs.exec(line))) {
143136
element = {
144137
url: parts[2],
145138
func: parts[1] || UNKNOWN_FUNCTION,
146-
args: [],
147139
line: +parts[3],
148140
column: parts[4] ? +parts[4] : null,
149141
};
150-
} else if ((parts = gecko.exec(lines[i]))) {
142+
} else if ((parts = gecko.exec(line))) {
151143
isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
152144
if (isEval && (submatch = geckoEval.exec(parts[3]))) {
153145
// throw out eval line/column and use top-most line number
154146
parts[1] = parts[1] || `eval`;
155147
parts[3] = submatch[1];
156148
parts[4] = submatch[2];
157149
parts[5] = ''; // no column when eval
158-
} else if (i === 0 && !parts[5] && ex.columnNumber !== void 0) {
159-
// FireFox uses this awesome columnNumber property for its top frame
160-
// Also note, Firefox's column number is 0-based and everything else expects 1-based,
161-
// so adding 1
162-
// NOTE: this hack doesn't work if top-most frame is eval
163-
stack[0].column = (ex.columnNumber as number) + 1;
164150
}
165151

166152
let url = parts[3];
@@ -170,18 +156,13 @@ function computeStackTraceFromStackProp(ex: any): StackTrace | null {
170156
element = {
171157
url,
172158
func,
173-
args: parts[2] ? parts[2].split(',') : [],
174159
line: parts[4] ? +parts[4] : null,
175160
column: parts[5] ? +parts[5] : null,
176161
};
177162
} else {
178163
continue;
179164
}
180165

181-
if (!element.func && element.line) {
182-
element.func = UNKNOWN_FUNCTION;
183-
}
184-
185166
stack.push(element);
186167
}
187168

@@ -208,7 +189,7 @@ function computeStackTraceFromStacktraceProp(ex: any): StackTrace | null {
208189
const stacktrace = ex.stacktrace;
209190
const opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
210191
const opera11Regex =
211-
/ line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\((.*)\))? in (.*):\s*$/i;
192+
/ line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\(.*\))? in (.*):\s*$/i;
212193
const lines = stacktrace.split('\n');
213194
const stack = [];
214195
let parts;
@@ -219,15 +200,13 @@ function computeStackTraceFromStacktraceProp(ex: any): StackTrace | null {
219200
element = {
220201
url: parts[2],
221202
func: parts[3],
222-
args: [],
223203
line: +parts[1],
224204
column: null,
225205
};
226206
} else if ((parts = opera11Regex.exec(lines[line]))) {
227207
element = {
228-
url: parts[6],
208+
url: parts[5],
229209
func: parts[3] || parts[4],
230-
args: parts[5] ? parts[5].split(',') : [],
231210
line: +parts[1],
232211
column: +parts[2],
233212
};

0 commit comments

Comments
 (0)