@@ -904,27 +904,23 @@ type ThrownInfo = {
904
904
export type ErrorInfo = ThrownInfo ;
905
905
export type PostponeInfo = ThrownInfo ;
906
906
907
- // While we track component stacks in prod all the time we only produce a reified stack in dev and
908
- // during prerender in Prod. The reason for this is that the stack is useful for prerender where the timeliness
909
- // of the request is less critical than the observability of the execution. For renders and resumes however we
910
- // prioritize speed of the request.
911
- function getThrownInfo (
912
- request : Request ,
913
- node : null | ComponentStackNode ,
914
- ) : ThrownInfo {
915
- if (
916
- node &&
917
- // Always produce a stack in dev
918
- ( __DEV__ ||
919
- // Produce a stack in prod if we're in a prerender
920
- request . trackedPostpones !== null )
921
- ) {
922
- return {
923
- componentStack : getStackFromNode ( node ) ,
924
- } ;
925
- } else {
926
- return { } ;
907
+ function getThrownInfo ( node : null | ComponentStackNode ) : ThrownInfo {
908
+ const errorInfo : ThrownInfo = { } ;
909
+ if ( node ) {
910
+ Object . defineProperty ( errorInfo , 'componentStack' , {
911
+ configurable : true ,
912
+ enumerable : true ,
913
+ get ( ) {
914
+ // Lazyily generate the stack since it's expensive.
915
+ const stack = getStackFromNode ( node ) ;
916
+ Object . defineProperty ( errorInfo , 'componentStack' , {
917
+ value : stack ,
918
+ } ) ;
919
+ return stack ;
920
+ } ,
921
+ } ) ;
927
922
}
923
+ return errorInfo ;
928
924
}
929
925
930
926
function encodeErrorForBoundary (
@@ -1123,7 +1119,7 @@ function renderSuspenseBoundary(
1123
1119
} catch ( error : mixed ) {
1124
1120
contentRootSegment . status = ERRORED ;
1125
1121
newBoundary . status = CLIENT_RENDERED ;
1126
- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
1122
+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
1127
1123
let errorDigest ;
1128
1124
if (
1129
1125
enablePostpone &&
@@ -1269,7 +1265,7 @@ function replaySuspenseBoundary(
1269
1265
}
1270
1266
} catch ( error : mixed ) {
1271
1267
resumedBoundary . status = CLIENT_RENDERED ;
1272
- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
1268
+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
1273
1269
let errorDigest ;
1274
1270
if (
1275
1271
enablePostpone &&
@@ -2333,7 +2329,7 @@ function replayElement(
2333
2329
// in the original prerender. What's unable to complete is the child
2334
2330
// replay nodes which might be Suspense boundaries which are able to
2335
2331
// absorb the error and we can still continue with siblings.
2336
- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
2332
+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
2337
2333
erroredReplay (
2338
2334
request ,
2339
2335
task . blockedBoundary ,
@@ -2864,7 +2860,7 @@ function replayFragment(
2864
2860
// replay nodes which might be Suspense boundaries which are able to
2865
2861
// absorb the error and we can still continue with siblings.
2866
2862
// This is an error, stash the component stack if it is null.
2867
- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
2863
+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
2868
2864
erroredReplay (
2869
2865
request ,
2870
2866
task . blockedBoundary ,
@@ -3457,7 +3453,7 @@ function renderNode(
3457
3453
const trackedPostpones = request . trackedPostpones ;
3458
3454
3459
3455
const postponeInstance : Postpone = ( x : any ) ;
3460
- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
3456
+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
3461
3457
const postponedSegment = injectPostponedHole (
3462
3458
request ,
3463
3459
( ( task : any ) : RenderTask ) , // We don't use ReplayTasks in prerenders.
@@ -3768,7 +3764,7 @@ function abortTask(task: Task, request: Request, error: mixed): void {
3768
3764
boundary . status = CLIENT_RENDERED ;
3769
3765
// We construct an errorInfo from the boundary's componentStack so the error in dev will indicate which
3770
3766
// boundary the message is referring to
3771
- const errorInfo = getThrownInfo ( request , task . componentStack ) ;
3767
+ const errorInfo = getThrownInfo ( task . componentStack ) ;
3772
3768
let errorDigest ;
3773
3769
if (
3774
3770
enablePostpone &&
@@ -4060,15 +4056,15 @@ function retryRenderTask(
4060
4056
task . abortSet . delete ( task ) ;
4061
4057
const postponeInstance : Postpone = ( x : any ) ;
4062
4058
4063
- const postponeInfo = getThrownInfo ( request , task . componentStack ) ;
4059
+ const postponeInfo = getThrownInfo ( task . componentStack ) ;
4064
4060
logPostpone ( request , postponeInstance . message , postponeInfo ) ;
4065
4061
trackPostpone ( request , trackedPostpones , task , segment ) ;
4066
4062
finishedTask ( request , task . blockedBoundary , segment ) ;
4067
4063
return ;
4068
4064
}
4069
4065
}
4070
4066
4071
- const errorInfo = getThrownInfo ( request , task . componentStack ) ;
4067
+ const errorInfo = getThrownInfo ( task . componentStack ) ;
4072
4068
task . abortSet . delete ( task ) ;
4073
4069
segment . status = ERRORED ;
4074
4070
erroredTask ( request , task . blockedBoundary , x , errorInfo ) ;
@@ -4142,7 +4138,7 @@ function retryReplayTask(request: Request, task: ReplayTask): void {
4142
4138
}
4143
4139
task . replay . pendingTasks -- ;
4144
4140
task . abortSet . delete ( task ) ;
4145
- const errorInfo = getThrownInfo ( request , task . componentStack ) ;
4141
+ const errorInfo = getThrownInfo ( task . componentStack ) ;
4146
4142
erroredReplay (
4147
4143
request ,
4148
4144
task . blockedBoundary ,
0 commit comments