Bug 1648875 - Fix stacktrace parsing when frame has multiple "@". r=loganfsmyth.

When parsing frames, we only need to retrieve the first "@" index to split
the frame string and get the function name on one side, and the location on the
other side.
This patch removes the regex-based search we were doing for a simpler character
search. A test is added to ensure this works as expected, and snapshots that were
highlighting the issue are updated.

Differential Revision: https://phabricator.services.mozilla.com/D81519
This commit is contained in:
Nicolas Chevobbe 2020-06-29 15:05:31 +00:00
parent 61b38f0a41
commit 269c35eaac
5 changed files with 138 additions and 39 deletions

View File

@ -231,20 +231,18 @@ function parseStackString(stack) {
let functionName;
let location;
// Given the input: "functionName@scriptLocation:2:100"
// Result: [
// "functionName@scriptLocation:2:100",
// "functionName",
// "scriptLocation:2:100"
// ]
const result = frame.match(/^(.*)@(.*)$/);
if (result && result.length === 3) {
functionName = result[1];
// Retrieve the index of the first @ to split the frame string.
const atCharIndex = frame.indexOf("@");
if (atCharIndex > -1) {
functionName = frame.slice(0, atCharIndex);
location = frame.slice(atCharIndex + 1);
}
if (location && location.includes(" -> ")) {
// If the resource was loaded by base-loader.js, the location looks like:
// resource://devtools/shared/base-loader.js -> resource://path/to/file.js .
// What's needed is only the last part after " -> ".
location = result[2].split(" -> ").pop();
location = location.split(" -> ").pop();
}
if (!functionName) {

View File

@ -353,4 +353,23 @@ stubs.set("Error with undefined-grip message", {
},
});
stubs.set("Error with stack having frames with multiple @", {
type: "object",
actor: "server1.conn1.child1/obj1021",
class: "Error",
ownPropertyLength: 4,
preview: {
kind: "Error",
name: "Error",
message: "bar",
stack:
"errorBar@https://example.com/turbo/from-npm.js@0.8.26/dist/from-npm.js:814:31\n" +
"errorFoo@https://example.com/turbo/from-npm.js@0.8.26/dist/from-npm.js:815:31\n" +
"@https://example.com/turbo/from-npm.js@0.8.26/dist/from-npm.js:816:31\n",
fileName: "from-npm.js",
lineNumber: 6,
columnNumber: 15,
},
});
module.exports = stubs;

View File

@ -55,6 +55,74 @@ exports[`Error - Error with invalid stack renders with expected text 1`] = `
</span>
`;
exports[`Error - Error with stack having frames with multiple @ renders with expected text for Error object 1`] = `
<span
className="objectBox-stackTrace reps-custom-format"
data-link-actor-id="server1.conn1.child1/obj1021"
title={null}
>
Error:
<span
className="objectBox objectBox-string"
>
bar
</span>
<span
className="objectBox-stackTrace-grid"
key="stack"
>
<span
className="objectBox-stackTrace-fn"
key="fn0"
>
errorBar
</span>
<span
className="objectBox-stackTrace-location"
key="location0"
>
https://example.com/turbo/from-npm.js@0.8.26/dist/from-npm.js:814:31
</span>
<span
className="objectBox-stackTrace-fn"
key="fn1"
>
errorFoo
</span>
<span
className="objectBox-stackTrace-location"
key="location1"
>
https://example.com/turbo/from-npm.js@0.8.26/dist/from-npm.js:815:31
</span>
<span
className="objectBox-stackTrace-fn"
key="fn2"
>
&lt;anonymous&gt;
</span>
<span
className="objectBox-stackTrace-location"
key="location2"
>
https://example.com/turbo/from-npm.js@0.8.26/dist/from-npm.js:816:31
</span>
</span>
</span>
`;
exports[`Error - Error with undefined-grip message renders with expected text 1`] = `
<span
className="objectBox-stackTrace reps-custom-format"
@ -892,14 +960,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn"
key="fn0"
>
node_modules
ngOnChanges
</span>
<span
className="objectBox-stackTrace-location"
key="location0"
>
angular/common/esm5/common.js:2656:27
webpack-internal:///./node_modules/@angular/common/esm5/common.js:2656:27
</span>
@ -908,14 +976,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn"
key="fn1"
>
node_modules
checkAndUpdateDirectiveInline
</span>
<span
className="objectBox-stackTrace-location"
key="location1"
>
angular/core/esm5/core.js:12581:9
webpack-internal:///./node_modules/@angular/core/esm5/core.js:12581:9
</span>
@ -924,14 +992,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn"
key="fn2"
>
node_modules
checkAndUpdateNodeInline
</span>
<span
className="objectBox-stackTrace-location"
key="location2"
>
angular/core/esm5/core.js:14109:20
webpack-internal:///./node_modules/@angular/core/esm5/core.js:14109:20
</span>
@ -940,14 +1008,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn"
key="fn3"
>
node_modules
checkAndUpdateNode
</span>
<span
className="objectBox-stackTrace-location"
key="location3"
>
angular/core/esm5/core.js:14052:16
webpack-internal:///./node_modules/@angular/core/esm5/core.js:14052:16
</span>
@ -956,14 +1024,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn"
key="fn4"
>
node_modules
debugCheckAndUpdateNode
</span>
<span
className="objectBox-stackTrace-location"
key="location4"
>
angular/core/esm5/core.js:14945:55
webpack-internal:///./node_modules/@angular/core/esm5/core.js:14945:55
</span>
@ -972,14 +1040,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn"
key="fn5"
>
node_modules
debugCheckDirectivesFn
</span>
<span
className="objectBox-stackTrace-location"
key="location5"
>
angular/core/esm5/core.js:14886:13
webpack-internal:///./node_modules/@angular/core/esm5/core.js:14886:13
</span>
@ -1004,14 +1072,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn"
key="fn7"
>
node_modules
debugUpdateDirectives
</span>
<span
className="objectBox-stackTrace-location"
key="location7"
>
angular/core/esm5/core.js:14871:12
webpack-internal:///./node_modules/@angular/core/esm5/core.js:14871:12
</span>
@ -1020,14 +1088,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn"
key="fn8"
>
node_modules
checkAndUpdateView
</span>
<span
className="objectBox-stackTrace-location"
key="location8"
>
angular/core/esm5/core.js:14018:5
webpack-internal:///./node_modules/@angular/core/esm5/core.js:14018:5
</span>
@ -1036,14 +1104,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn"
key="fn9"
>
node_modules
callViewAction
</span>
<span
className="objectBox-stackTrace-location"
key="location9"
>
angular/core/esm5/core.js:14369:21
webpack-internal:///./node_modules/@angular/core/esm5/core.js:14369:21
</span>

View File

@ -722,3 +722,18 @@ describe("Error - Error with undefined-grip message", () => {
expect(tinyRenderedComponent).toMatchSnapshot();
});
});
describe("Error - Error with stack having frames with multiple @", () => {
const stub = stubs.get("Error with stack having frames with multiple @");
it("renders with expected text for Error object", () => {
const renderedComponent = shallow(
ErrorRep.rep({
object: stub,
customFormat: true,
})
);
expect(renderedComponent).toMatchSnapshot();
});
});

View File

@ -3293,21 +3293,20 @@ function parseStackString(stack) {
}
let functionName;
let location; // Given the input: "functionName@scriptLocation:2:100"
// Result: [
// "functionName@scriptLocation:2:100",
// "functionName",
// "scriptLocation:2:100"
// ]
let location; // Retrieve the index of the first @ to split the frame string.
const result = frame.match(/^(.*)@(.*)$/);
const atCharIndex = frame.indexOf("@");
if (result && result.length === 3) {
functionName = result[1]; // If the resource was loaded by base-loader.js, the location looks like:
if (atCharIndex > -1) {
functionName = frame.slice(0, atCharIndex);
location = frame.slice(atCharIndex + 1);
}
if (location && location.includes(" -> ")) {
// If the resource was loaded by base-loader.js, the location looks like:
// resource://devtools/shared/base-loader.js -> resource://path/to/file.js .
// What's needed is only the last part after " -> ".
location = result[2].split(" -> ").pop();
location = location.split(" -> ").pop();
}
if (!functionName) {