@@ -904,27 +904,23 @@ type ThrownInfo = {
904904export type ErrorInfo = ThrownInfo ;
905905export type PostponeInfo = ThrownInfo ;
906906
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+ } ) ;
927922 }
923+ return errorInfo ;
928924}
929925
930926function encodeErrorForBoundary (
@@ -1123,7 +1119,7 @@ function renderSuspenseBoundary(
11231119 } catch ( error : mixed ) {
11241120 contentRootSegment . status = ERRORED ;
11251121 newBoundary . status = CLIENT_RENDERED ;
1126- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
1122+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
11271123 let errorDigest ;
11281124 if (
11291125 enablePostpone &&
@@ -1269,7 +1265,7 @@ function replaySuspenseBoundary(
12691265 }
12701266 } catch ( error : mixed ) {
12711267 resumedBoundary . status = CLIENT_RENDERED ;
1272- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
1268+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
12731269 let errorDigest ;
12741270 if (
12751271 enablePostpone &&
@@ -2333,7 +2329,7 @@ function replayElement(
23332329 // in the original prerender. What's unable to complete is the child
23342330 // replay nodes which might be Suspense boundaries which are able to
23352331 // absorb the error and we can still continue with siblings.
2336- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
2332+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
23372333 erroredReplay (
23382334 request ,
23392335 task . blockedBoundary ,
@@ -2864,7 +2860,7 @@ function replayFragment(
28642860 // replay nodes which might be Suspense boundaries which are able to
28652861 // absorb the error and we can still continue with siblings.
28662862 // 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 ) ;
28682864 erroredReplay (
28692865 request ,
28702866 task . blockedBoundary ,
@@ -3457,7 +3453,7 @@ function renderNode(
34573453 const trackedPostpones = request . trackedPostpones ;
34583454
34593455 const postponeInstance : Postpone = ( x : any ) ;
3460- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
3456+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
34613457 const postponedSegment = injectPostponedHole (
34623458 request ,
34633459 ( ( task : any ) : RenderTask ) , // We don't use ReplayTasks in prerenders.
@@ -3768,7 +3764,7 @@ function abortTask(task: Task, request: Request, error: mixed): void {
37683764 boundary . status = CLIENT_RENDERED ;
37693765 // We construct an errorInfo from the boundary's componentStack so the error in dev will indicate which
37703766 // boundary the message is referring to
3771- const errorInfo = getThrownInfo ( request , task . componentStack ) ;
3767+ const errorInfo = getThrownInfo ( task . componentStack ) ;
37723768 let errorDigest ;
37733769 if (
37743770 enablePostpone &&
@@ -4060,15 +4056,15 @@ function retryRenderTask(
40604056 task . abortSet . delete ( task ) ;
40614057 const postponeInstance : Postpone = ( x : any ) ;
40624058
4063- const postponeInfo = getThrownInfo ( request , task . componentStack ) ;
4059+ const postponeInfo = getThrownInfo ( task . componentStack ) ;
40644060 logPostpone ( request , postponeInstance . message , postponeInfo ) ;
40654061 trackPostpone ( request , trackedPostpones , task , segment ) ;
40664062 finishedTask ( request , task . blockedBoundary , segment ) ;
40674063 return ;
40684064 }
40694065 }
40704066
4071- const errorInfo = getThrownInfo ( request , task . componentStack ) ;
4067+ const errorInfo = getThrownInfo ( task . componentStack ) ;
40724068 task . abortSet . delete ( task ) ;
40734069 segment . status = ERRORED ;
40744070 erroredTask ( request , task . blockedBoundary , x , errorInfo ) ;
@@ -4142,7 +4138,7 @@ function retryReplayTask(request: Request, task: ReplayTask): void {
41424138 }
41434139 task . replay . pendingTasks -- ;
41444140 task . abortSet . delete ( task ) ;
4145- const errorInfo = getThrownInfo ( request , task . componentStack ) ;
4141+ const errorInfo = getThrownInfo ( task . componentStack ) ;
41464142 erroredReplay (
41474143 request ,
41484144 task . blockedBoundary ,
0 commit comments