Skip to content

Commit 12ae91a

Browse files
authored
allow parsing stack traces that end with "skipping x frames" (#195)
1 parent 875a31a commit 12ae91a

File tree

1 file changed

+44
-20
lines changed

1 file changed

+44
-20
lines changed

front_end/panels/console/ErrorStackParser.ts

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,37 +21,48 @@ export interface ParsedErrorFrame {
2121
};
2222
}
2323

24-
export type SpecialHermesStackTraceFrameTypes = 'native' | 'address at' | 'empty url';
25-
26-
function getSpecialHermesStackTraceFrameType({
27-
url,
28-
}: {
29-
url: Platform.DevToolsPath.UrlString,
30-
}): SpecialHermesStackTraceFrameTypes | null {
31-
// functions implemented in c++.
32-
// TODO: these might be enhanced to include the C++ loc for the frame
33-
// so that a debugger could stitch together a hybrid cross-language call stack
24+
export type SpecialHermesStackTraceFrameTypes =
25+
// e.g "(native)"- Functions implemented on the native side.
26+
// TODO: Might be enhanced to include the native (C++/Java/etc) loc
27+
// for the frame so that a debugger could stitch together a
28+
// hybrid cross-language call stack
29+
'native' |
30+
// e.g "(:3:4)"- Frames with empty url
31+
// TODO: Seems to be happening due to a bug that needs to be investigated
32+
// and produce an actual script URL instead
33+
'empty url' |
34+
// e.g "(address at InternalBytecode.js:5:6)"- Frames pointing to bytecode locations
35+
// TODO: Could be symbolicated and link to source files with the help of
36+
// a bytecode source maps once they are available.
37+
'address at' |
38+
// e.g " ... skipping 7 frames" - Frames collapsed in the middle of a stack trace
39+
// for very long stack traces
40+
'skipping x frames' ;
41+
42+
function getSpecialHermesFrameBasedOnURL(url: string): SpecialHermesStackTraceFrameTypes | null {
3443
if (url === 'native') {
3544
return 'native';
3645
}
3746

38-
// frames with empty url
39-
// TODO: these seem to be happening due to a bug that needs to be investigated
40-
// and produce an actual script URL instead
4147
if (url === '') {
4248
return 'empty url';
4349
}
4450

45-
// frames pointing to a bytecode locations
46-
// TODO: these could be symbolicated and link to source files with the help of
47-
// a bytecode source maps once they are available.
4851
if (url.startsWith?.('address at ')) {
4952
return 'address at';
5053
}
5154

5255
return null;
5356
}
5457

58+
function getSpecialHermesFrameBasedOnLine(line: string): SpecialHermesStackTraceFrameTypes | null {
59+
if (/^\s*... skipping \d+ frames$/.exec(line)) {
60+
return 'skipping x frames';
61+
}
62+
63+
return null;
64+
}
65+
5566
/**
5667
* Takes a V8 Error#stack string and extracts source position information.
5768
*
@@ -77,6 +88,18 @@ export function parseSourcePositionsFromErrorStack(
7788
const match = /^\s*at\s(async\s)?/.exec(line);
7889
if (!match) {
7990
if (linkInfos.length && linkInfos[linkInfos.length - 1].isCallFrame) {
91+
const specialHermesFrameType = getSpecialHermesFrameBasedOnLine(line);
92+
if (specialHermesFrameType) {
93+
specialHermesFramesParsed.add(specialHermesFrameType);
94+
if (!linkInfos[linkInfos.length - 1].link) {
95+
// Combine builtin frames.
96+
linkInfos[linkInfos.length - 1].line += `\n${line}`;
97+
} else {
98+
linkInfos.push({line, isCallFrame: false});
99+
}
100+
continue;
101+
}
102+
80103
Host.rnPerfMetrics.stackTraceSymbolicationFailed(stack, line, '"at (url)" not found');
81104
return null;
82105
}
@@ -112,17 +135,18 @@ export function parseSourcePositionsFromErrorStack(
112135

113136
const linkCandidate = line.substring(left, right);
114137
const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(linkCandidate);
115-
const specialHermesFrameType = getSpecialHermesStackTraceFrameType(splitResult);
138+
const specialHermesFrameType = getSpecialHermesFrameBasedOnURL(splitResult.url);
139+
if (specialHermesFrameType) {
140+
specialHermesFramesParsed.add(specialHermesFrameType);
141+
}
142+
116143
if (splitResult.url === '<anonymous>' || specialHermesFrameType !== null) {
117144
if (linkInfos.length && linkInfos[linkInfos.length - 1].isCallFrame && !linkInfos[linkInfos.length - 1].link) {
118145
// Combine builtin frames.
119146
linkInfos[linkInfos.length - 1].line += `\n${line}`;
120147
} else {
121148
linkInfos.push({line, isCallFrame});
122149
}
123-
if (specialHermesFrameType !== null) {
124-
specialHermesFramesParsed.add(specialHermesFrameType);
125-
}
126150
continue;
127151
}
128152
let url = parseOrScriptMatch(debuggerModel, splitResult.url);

0 commit comments

Comments
 (0)