@@ -21,37 +21,57 @@ 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 "(eval:1:2)"- Seem to be reported when there's a
31+ // ReferenceError or TypeError during the initial bundle code execution.
32+ // TODO: Understand exactly where these originate from and what further work
33+ // should be done in regards to them
34+ 'eval' |
35+ // e.g "(:3:4)"- Frames with empty url
36+ // TODO: Seems to be happening due to a bug that needs to be investigated
37+ // and produce an actual script URL instead
38+ 'empty url' |
39+ // e.g "(address at InternalBytecode.js:5:6)"- Frames pointing to bytecode locations
40+ // TODO: Could be symbolicated and link to source files with the help of
41+ // a bytecode source maps once they are available.
42+ 'address at' |
43+ // e.g " ... skipping 7 frames" - Frames collapsed in the middle of a stack trace
44+ // for very long stack traces
45+ 'skipping x frames' ;
46+
47+ function getSpecialHermesFrameBasedOnURL ( url : string ) : SpecialHermesStackTraceFrameTypes | null {
3448 if ( url === 'native' ) {
3549 return 'native' ;
3650 }
3751
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
52+ if ( url === 'eval' ) {
53+ return 'eval' ;
54+ }
55+
4156 if ( url === '' ) {
4257 return 'empty url' ;
4358 }
4459
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.
4860 if ( url . startsWith ?.( 'address at ' ) ) {
4961 return 'address at' ;
5062 }
5163
5264 return null ;
5365}
5466
67+ function getSpecialHermesFrameBasedOnLine ( line : string ) : SpecialHermesStackTraceFrameTypes | null {
68+ if ( / ^ \s * ... s k i p p i n g \d + f r a m e s $ / . exec ( line ) ) {
69+ return 'skipping x frames' ;
70+ }
71+
72+ return null ;
73+ }
74+
5575/**
5676 * Takes a V8 Error#stack string and extracts source position information.
5777 *
@@ -71,10 +91,24 @@ export function parseSourcePositionsFromErrorStack(
7191
7292 const lines = stack . split ( '\n' ) ;
7393 const linkInfos = [ ] ;
94+ const specialHermesFramesParsed = new Set < SpecialHermesStackTraceFrameTypes > ( ) ;
95+
7496 for ( const line of lines ) {
7597 const match = / ^ \s * a t \s ( a s y n c \s ) ? / . exec ( line ) ;
7698 if ( ! match ) {
7799 if ( linkInfos . length && linkInfos [ linkInfos . length - 1 ] . isCallFrame ) {
100+ const specialHermesFrameType = getSpecialHermesFrameBasedOnLine ( line ) ;
101+ if ( specialHermesFrameType !== null ) {
102+ specialHermesFramesParsed . add ( specialHermesFrameType ) ;
103+ if ( ! linkInfos [ linkInfos . length - 1 ] . link ) {
104+ // Combine builtin frames.
105+ linkInfos [ linkInfos . length - 1 ] . line += `\n${ line } ` ;
106+ } else {
107+ linkInfos . push ( { line, isCallFrame : false } ) ;
108+ }
109+ continue ;
110+ }
111+
78112 Host . rnPerfMetrics . stackTraceSymbolicationFailed ( stack , line , '"at (url)" not found' ) ;
79113 return null ;
80114 }
@@ -110,7 +144,11 @@ export function parseSourcePositionsFromErrorStack(
110144
111145 const linkCandidate = line . substring ( left , right ) ;
112146 const splitResult = Common . ParsedURL . ParsedURL . splitLineAndColumn ( linkCandidate ) ;
113- const specialHermesFrameType = getSpecialHermesStackTraceFrameType ( splitResult ) ;
147+ const specialHermesFrameType = getSpecialHermesFrameBasedOnURL ( splitResult . url ) ;
148+ if ( specialHermesFrameType !== null ) {
149+ specialHermesFramesParsed . add ( specialHermesFrameType ) ;
150+ }
151+
114152 if ( splitResult . url === '<anonymous>' || specialHermesFrameType !== null ) {
115153 if ( linkInfos . length && linkInfos [ linkInfos . length - 1 ] . isCallFrame && ! linkInfos [ linkInfos . length - 1 ] . link ) {
116154 // Combine builtin frames.
@@ -142,6 +180,11 @@ export function parseSourcePositionsFromErrorStack(
142180 } ,
143181 } ) ;
144182 }
183+
184+ if ( linkInfos ?. length ) {
185+ Host . rnPerfMetrics . stackTraceSymbolicationSucceeded ( Array . from ( specialHermesFramesParsed ) ) ;
186+ }
187+
145188 return linkInfos ;
146189}
147190
0 commit comments