@@ -856,27 +856,23 @@ type ThrownInfo = {
856856export type ErrorInfo = ThrownInfo ;
857857export type PostponeInfo = ThrownInfo ;
858858
859- // While we track component stacks in prod all the time we only produce a reified stack in dev and
860- // during prerender in Prod. The reason for this is that the stack is useful for prerender where the timeliness
861- // of the request is less critical than the observability of the execution. For renders and resumes however we
862- // prioritize speed of the request.
863- function getThrownInfo (
864- request : Request ,
865- node : null | ComponentStackNode ,
866- ) : ThrownInfo {
867- if (
868- node &&
869- // Always produce a stack in dev
870- ( __DEV__ ||
871- // Produce a stack in prod if we're in a prerender
872- request . trackedPostpones !== null )
873- ) {
874- return {
875- componentStack : getStackFromNode ( node ) ,
876- } ;
877- } else {
878- return { } ;
859+ function getThrownInfo ( node : null | ComponentStackNode ) : ThrownInfo {
860+ const errorInfo : ThrownInfo = { } ;
861+ if ( node ) {
862+ Object . defineProperty ( errorInfo , 'componentStack' , {
863+ configurable : true ,
864+ enumerable : true ,
865+ get ( ) {
866+ // Lazyily generate the stack since it's expensive.
867+ const stack = getStackFromNode ( node ) ;
868+ Object . defineProperty ( errorInfo , 'componentStack' , {
869+ value : stack ,
870+ } ) ;
871+ return stack ;
872+ } ,
873+ } ) ;
879874 }
875+ return errorInfo ;
880876}
881877
882878function encodeErrorForBoundary (
@@ -1073,7 +1069,7 @@ function renderSuspenseBoundary(
10731069 } catch ( error : mixed ) {
10741070 contentRootSegment . status = ERRORED ;
10751071 newBoundary . status = CLIENT_RENDERED ;
1076- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
1072+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
10771073 let errorDigest ;
10781074 if (
10791075 enablePostpone &&
@@ -1217,7 +1213,7 @@ function replaySuspenseBoundary(
12171213 }
12181214 } catch ( error : mixed ) {
12191215 resumedBoundary . status = CLIENT_RENDERED ;
1220- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
1216+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
12211217 let errorDigest ;
12221218 if (
12231219 enablePostpone &&
@@ -2172,7 +2168,7 @@ function replayElement(
21722168 // in the original prerender. What's unable to complete is the child
21732169 // replay nodes which might be Suspense boundaries which are able to
21742170 // absorb the error and we can still continue with siblings.
2175- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
2171+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
21762172 erroredReplay (
21772173 request ,
21782174 task . blockedBoundary ,
@@ -2642,7 +2638,7 @@ function replayFragment(
26422638 // replay nodes which might be Suspense boundaries which are able to
26432639 // absorb the error and we can still continue with siblings.
26442640 // This is an error, stash the component stack if it is null.
2645- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
2641+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
26462642 erroredReplay (
26472643 request ,
26482644 task . blockedBoundary ,
@@ -3195,7 +3191,7 @@ function renderNode(
31953191 const trackedPostpones = request . trackedPostpones ;
31963192
31973193 const postponeInstance : Postpone = ( x : any ) ;
3198- const thrownInfo = getThrownInfo ( request , task . componentStack ) ;
3194+ const thrownInfo = getThrownInfo ( task . componentStack ) ;
31993195 const postponedSegment = injectPostponedHole (
32003196 request ,
32013197 ( ( task : any ) : RenderTask ) , // We don't use ReplayTasks in prerenders.
@@ -3506,7 +3502,7 @@ function abortTask(task: Task, request: Request, error: mixed): void {
35063502 boundary . status = CLIENT_RENDERED ;
35073503 // We construct an errorInfo from the boundary's componentStack so the error in dev will indicate which
35083504 // boundary the message is referring to
3509- const errorInfo = getThrownInfo ( request , task . componentStack ) ;
3505+ const errorInfo = getThrownInfo ( task . componentStack ) ;
35103506 let errorDigest ;
35113507 if (
35123508 enablePostpone &&
@@ -3798,15 +3794,15 @@ function retryRenderTask(
37983794 task . abortSet . delete ( task ) ;
37993795 const postponeInstance : Postpone = ( x : any ) ;
38003796
3801- const postponeInfo = getThrownInfo ( request , task . componentStack ) ;
3797+ const postponeInfo = getThrownInfo ( task . componentStack ) ;
38023798 logPostpone ( request , postponeInstance . message , postponeInfo ) ;
38033799 trackPostpone ( request , trackedPostpones , task , segment ) ;
38043800 finishedTask ( request , task . blockedBoundary , segment ) ;
38053801 return ;
38063802 }
38073803 }
38083804
3809- const errorInfo = getThrownInfo ( request , task . componentStack ) ;
3805+ const errorInfo = getThrownInfo ( task . componentStack ) ;
38103806 task . abortSet . delete ( task ) ;
38113807 segment . status = ERRORED ;
38123808 erroredTask ( request , task . blockedBoundary , x , errorInfo ) ;
@@ -3880,7 +3876,7 @@ function retryReplayTask(request: Request, task: ReplayTask): void {
38803876 }
38813877 task . replay . pendingTasks -- ;
38823878 task . abortSet . delete ( task ) ;
3883- const errorInfo = getThrownInfo ( request , task . componentStack ) ;
3879+ const errorInfo = getThrownInfo ( task . componentStack ) ;
38843880 erroredReplay (
38853881 request ,
38863882 task . blockedBoundary ,
0 commit comments