@@ -64,6 +64,7 @@ import type {
64
64
ReactAsyncInfo ,
65
65
ReactTimeInfo ,
66
66
ReactStackTrace ,
67
+ ReactCallSite ,
67
68
ReactFunctionLocation ,
68
69
ReactErrorInfo ,
69
70
ReactErrorInfoDev ,
@@ -166,16 +167,14 @@ function defaultFilterStackFrame(
166
167
167
168
function filterStackTrace(
168
169
request: Request,
169
- error: Error,
170
- skipFrames: number,
170
+ stack: ReactStackTrace,
171
171
): ReactStackTrace {
172
172
// Since stacks can be quite large and we pass a lot of them, we filter them out eagerly
173
173
// to save bandwidth even in DEV. We'll also replay these stacks on the client so by
174
174
// stripping them early we avoid that overhead. Otherwise we'd normally just rely on
175
175
// the DevTools or framework's ignore lists to filter them out.
176
176
const filterStackFrame = request . filterStackFrame ;
177
- const stack = parseStackTrace ( error , skipFrames ) ;
178
- const filteredStack = [ ] ;
177
+ const filteredStack : ReactStackTrace = [ ] ;
179
178
for ( let i = 0 ; i < stack . length ; i ++ ) {
180
179
const callsite = stack [ i ] ;
181
180
const functionName = callsite [ 0 ] ;
@@ -194,7 +193,7 @@ function filterStackTrace(
194
193
if ( filterStackFrame ( url , functionName ) ) {
195
194
// Use a clone because the Flight protocol isn't yet resilient to deduping
196
195
// objects in the debug info. TODO: Support deduping stacks.
197
- const clone = callsite . slice ( 0 ) ;
196
+ const clone : ReactCallSite = ( callsite . slice ( 0 ) : any ) ;
198
197
clone [ 1 ] = url ;
199
198
filteredStack . push ( clone ) ;
200
199
}
@@ -227,8 +226,7 @@ function patchConsole(consoleInst: typeof console, methodName: string) {
227
226
// one stack frame but keeping it simple for now and include all frames.
228
227
const stack = filterStackTrace (
229
228
request ,
230
- new Error ( 'react-stack-top-frame' ) ,
231
- 1 ,
229
+ parseStackTrace ( new Error ( 'react-stack-top-frame' ) , 1 ) ,
232
230
) ;
233
231
request . pendingChunks ++ ;
234
232
const owner : null | ReactComponentInfo = resolveOwner ( ) ;
@@ -1065,7 +1063,7 @@ function callWithDebugContextInDEV<A, T>(
1065
1063
componentDebugInfo . stack =
1066
1064
task . debugStack === null
1067
1065
? null
1068
- : filterStackTrace ( request , task . debugStack , 1 ) ;
1066
+ : filterStackTrace ( request , parseStackTrace ( task . debugStack , 1 ) ) ;
1069
1067
// $FlowFixMe[cannot-write]
1070
1068
componentDebugInfo . debugStack = task . debugStack ;
1071
1069
// $FlowFixMe[cannot-write]
@@ -1266,7 +1264,7 @@ function renderFunctionComponent<Props>(
1266
1264
componentDebugInfo . stack =
1267
1265
task . debugStack === null
1268
1266
? null
1269
- : filterStackTrace ( request , task . debugStack , 1 ) ;
1267
+ : filterStackTrace ( request , parseStackTrace ( task . debugStack , 1 ) ) ;
1270
1268
// $FlowFixMe[cannot-write]
1271
1269
componentDebugInfo . props = props ;
1272
1270
// $FlowFixMe[cannot-write]
@@ -1602,7 +1600,7 @@ function renderClientElement(
1602
1600
task . debugOwner ,
1603
1601
task . debugStack === null
1604
1602
? null
1605
- : filterStackTrace ( request , task . debugStack , 1 ) ,
1603
+ : filterStackTrace ( request , parseStackTrace ( task . debugStack , 1 ) ) ,
1606
1604
validated ,
1607
1605
]
1608
1606
: [ REACT_ELEMENT_TYPE , type , key , props ] ;
@@ -1735,7 +1733,7 @@ function renderElement(
1735
1733
stack :
1736
1734
task . debugStack === null
1737
1735
? null
1738
- : filterStackTrace ( request , task . debugStack , 1 ) ,
1736
+ : filterStackTrace ( request , parseStackTrace ( task . debugStack , 1 ) ) ,
1739
1737
props : props ,
1740
1738
debugStack : task . debugStack ,
1741
1739
debugTask : task . debugTask ,
@@ -1864,7 +1862,10 @@ function visitAsyncNode(
1864
1862
// We don't log it yet though. We return it to be logged by the point where it's awaited.
1865
1863
// The ioNode might be another PromiseNode in the case where none of the AwaitNode had
1866
1864
// unfiltered stacks.
1867
- if ( filterStackTrace ( request , node . stack , 1 ) . length === 0 ) {
1865
+ if (
1866
+ filterStackTrace ( request , parseStackTrace ( node . stack , 1 ) ) . length ===
1867
+ 0
1868
+ ) {
1868
1869
// Typically we assume that the outer most Promise that was awaited in user space has the
1869
1870
// most actionable stack trace for the start of the operation. However, if this Promise
1870
1871
// Promise was created inside only third party code, then try to use the inner node instead.
@@ -1885,7 +1886,10 @@ function visitAsyncNode(
1885
1886
if ( awaited !== null ) {
1886
1887
const ioNode = visitAsyncNode ( request , task , awaited , cutOff , visited ) ;
1887
1888
if ( ioNode !== null ) {
1888
- const stack = filterStackTrace ( request , node . stack , 1 ) ;
1889
+ const stack = filterStackTrace (
1890
+ request ,
1891
+ parseStackTrace ( node . stack , 1 ) ,
1892
+ ) ;
1889
1893
if ( stack . length === 0 ) {
1890
1894
// If this await was fully filtered out, then it was inside third party code
1891
1895
// such as in an external library. We return the I/O node and try another await.
@@ -3259,7 +3263,7 @@ function emitPostponeChunk(
3259
3263
try {
3260
3264
// eslint-disable-next-line react-internal/safe-string-coercion
3261
3265
reason = String ( postponeInstance . message ) ;
3262
- stack = filterStackTrace ( request , postponeInstance , 0 ) ;
3266
+ stack = filterStackTrace ( request , parseStackTrace ( postponeInstance , 0 ) ) ;
3263
3267
} catch ( x ) {
3264
3268
stack = [ ] ;
3265
3269
}
@@ -3282,7 +3286,7 @@ function serializeErrorValue(request: Request, error: Error): string {
3282
3286
name = error . name ;
3283
3287
// eslint-disable-next-line react-internal/safe-string-coercion
3284
3288
message = String ( error . message ) ;
3285
- stack = filterStackTrace ( request , error , 0 ) ;
3289
+ stack = filterStackTrace ( request , parseStackTrace ( error , 0 ) ) ;
3286
3290
const errorEnv = ( error : any ) . environmentName ;
3287
3291
if ( typeof errorEnv === 'string' ) {
3288
3292
// This probably came from another FlightClient as a pass through.
@@ -3321,7 +3325,7 @@ function emitErrorChunk(
3321
3325
name = error . name ;
3322
3326
// eslint-disable-next-line react-internal/safe-string-coercion
3323
3327
message = String ( error . message ) ;
3324
- stack = filterStackTrace ( request , error , 0 ) ;
3328
+ stack = filterStackTrace ( request , parseStackTrace ( error , 0 ) ) ;
3325
3329
const errorEnv = ( error : any ) . environmentName ;
3326
3330
if ( typeof errorEnv === 'string' ) {
3327
3331
// This probably came from another FlightClient as a pass through.
@@ -3564,7 +3568,7 @@ function serializeIONode(
3564
3568
let stack = null ;
3565
3569
let name = '';
3566
3570
if ( ioNode . stack !== null ) {
3567
- stack = filterStackTrace ( request , ioNode . stack , 1 ) ;
3571
+ stack = filterStackTrace ( request , parseStackTrace ( ioNode . stack , 1 ) ) ;
3568
3572
name = '';
3569
3573
}
3570
3574
request . pendingChunks ++ ;
@@ -3710,7 +3714,10 @@ function renderConsoleValue(
3710
3714
let debugStack : null | ReactStackTrace = null ;
3711
3715
if ( element . _debugStack != null ) {
3712
3716
// Outline the debug stack so that it doesn't get cut off.
3713
- debugStack = filterStackTrace ( request , element . _debugStack , 1 ) ;
3717
+ debugStack = filterStackTrace (
3718
+ request ,
3719
+ parseStackTrace ( element . _debugStack , 1 ) ,
3720
+ ) ;
3714
3721
doNotLimit . add ( debugStack ) ;
3715
3722
for ( let i = 0 ; i < debugStack . length ; i ++ ) {
3716
3723
doNotLimit . add ( debugStack [ i ] ) ;
0 commit comments