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

View File

@ -55,6 +55,74 @@ exports[`Error - Error with invalid stack renders with expected text 1`] = `
</span> </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`] = ` exports[`Error - Error with undefined-grip message renders with expected text 1`] = `
<span <span
className="objectBox-stackTrace reps-custom-format" className="objectBox-stackTrace reps-custom-format"
@ -892,14 +960,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn" className="objectBox-stackTrace-fn"
key="fn0" key="fn0"
> >
node_modules ngOnChanges
</span> </span>
<span <span
className="objectBox-stackTrace-location" className="objectBox-stackTrace-location"
key="location0" key="location0"
> >
angular/common/esm5/common.js:2656:27 webpack-internal:///./node_modules/@angular/common/esm5/common.js:2656:27
</span> </span>
@ -908,14 +976,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn" className="objectBox-stackTrace-fn"
key="fn1" key="fn1"
> >
node_modules checkAndUpdateDirectiveInline
</span> </span>
<span <span
className="objectBox-stackTrace-location" className="objectBox-stackTrace-location"
key="location1" key="location1"
> >
angular/core/esm5/core.js:12581:9 webpack-internal:///./node_modules/@angular/core/esm5/core.js:12581:9
</span> </span>
@ -924,14 +992,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn" className="objectBox-stackTrace-fn"
key="fn2" key="fn2"
> >
node_modules checkAndUpdateNodeInline
</span> </span>
<span <span
className="objectBox-stackTrace-location" className="objectBox-stackTrace-location"
key="location2" key="location2"
> >
angular/core/esm5/core.js:14109:20 webpack-internal:///./node_modules/@angular/core/esm5/core.js:14109:20
</span> </span>
@ -940,14 +1008,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn" className="objectBox-stackTrace-fn"
key="fn3" key="fn3"
> >
node_modules checkAndUpdateNode
</span> </span>
<span <span
className="objectBox-stackTrace-location" className="objectBox-stackTrace-location"
key="location3" key="location3"
> >
angular/core/esm5/core.js:14052:16 webpack-internal:///./node_modules/@angular/core/esm5/core.js:14052:16
</span> </span>
@ -956,14 +1024,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn" className="objectBox-stackTrace-fn"
key="fn4" key="fn4"
> >
node_modules debugCheckAndUpdateNode
</span> </span>
<span <span
className="objectBox-stackTrace-location" className="objectBox-stackTrace-location"
key="location4" key="location4"
> >
angular/core/esm5/core.js:14945:55 webpack-internal:///./node_modules/@angular/core/esm5/core.js:14945:55
</span> </span>
@ -972,14 +1040,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn" className="objectBox-stackTrace-fn"
key="fn5" key="fn5"
> >
node_modules debugCheckDirectivesFn
</span> </span>
<span <span
className="objectBox-stackTrace-location" className="objectBox-stackTrace-location"
key="location5" key="location5"
> >
angular/core/esm5/core.js:14886:13 webpack-internal:///./node_modules/@angular/core/esm5/core.js:14886:13
</span> </span>
@ -1004,14 +1072,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn" className="objectBox-stackTrace-fn"
key="fn7" key="fn7"
> >
node_modules debugUpdateDirectives
</span> </span>
<span <span
className="objectBox-stackTrace-location" className="objectBox-stackTrace-location"
key="location7" key="location7"
> >
angular/core/esm5/core.js:14871:12 webpack-internal:///./node_modules/@angular/core/esm5/core.js:14871:12
</span> </span>
@ -1020,14 +1088,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn" className="objectBox-stackTrace-fn"
key="fn8" key="fn8"
> >
node_modules checkAndUpdateView
</span> </span>
<span <span
className="objectBox-stackTrace-location" className="objectBox-stackTrace-location"
key="location8" key="location8"
> >
angular/core/esm5/core.js:14018:5 webpack-internal:///./node_modules/@angular/core/esm5/core.js:14018:5
</span> </span>
@ -1036,14 +1104,14 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
className="objectBox-stackTrace-fn" className="objectBox-stackTrace-fn"
key="fn9" key="fn9"
> >
node_modules callViewAction
</span> </span>
<span <span
className="objectBox-stackTrace-location" className="objectBox-stackTrace-location"
key="location9" key="location9"
> >
angular/core/esm5/core.js:14369:21 webpack-internal:///./node_modules/@angular/core/esm5/core.js:14369:21
</span> </span>

View File

@ -722,3 +722,18 @@ describe("Error - Error with undefined-grip message", () => {
expect(tinyRenderedComponent).toMatchSnapshot(); 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 functionName;
let location; // Given the input: "functionName@scriptLocation:2:100" let location; // Retrieve the index of the first @ to split the frame string.
// Result: [
// "functionName@scriptLocation:2:100",
// "functionName",
// "scriptLocation:2:100"
// ]
const result = frame.match(/^(.*)@(.*)$/); const atCharIndex = frame.indexOf("@");
if (result && result.length === 3) { if (atCharIndex > -1) {
functionName = result[1]; // If the resource was loaded by base-loader.js, the location looks like: 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 . // resource://devtools/shared/base-loader.js -> resource://path/to/file.js .
// What's needed is only the last part after " -> ". // What's needed is only the last part after " -> ".
location = location.split(" -> ").pop();
location = result[2].split(" -> ").pop();
} }
if (!functionName) { if (!functionName) {