908
export type ErrorInfo = ThrownInfo;
909
export type PostponeInfo = ThrownInfo;
910
911
-// While we track component stacks in prod all the time we only produce a reified stack in dev and
912
-// during prerender in Prod. The reason for this is that the stack is useful for prerender where the timeliness
913
-// of the request is less critical than the observability of the execution. For renders and resumes however we
914
-// prioritize speed of the request.
915
-function getThrownInfo(
916
- request: Request,
917
- node: null | ComponentStackNode,
918
-): ThrownInfo {
919
- if (
920
- node &&
921
- // Always produce a stack in dev
922
- (__DEV__ ||
923
- // Produce a stack in prod if we're in a prerender
924
- request.trackedPostpones !== null)
925
- ) {
926
- return {
927
- componentStack: getStackFromNode(node),
928
- };
929
- } else {
930
- return {};
911
+function getThrownInfo(node: null | ComponentStackNode): ThrownInfo {
912
+ const errorInfo: ThrownInfo = {};
913
+ if (node) {
914
+ Object.defineProperty(errorInfo, 'componentStack', {
915
+ configurable: true,
916
+ enumerable: true,
917
+ get() {
918
+ // Lazyily generate the stack since it's expensive.
919
+ const stack = getStackFromNode(node);
920
+ Object.defineProperty(errorInfo, 'componentStack', {
921
+ value: stack,
922
+ });
923
+ return stack;
924
+ },
925
+ });
926
}
927
+ return errorInfo;
928
}
929
930
function encodeErrorForBoundary(
1123
} catch (error: mixed) {
1124
contentRootSegment.status = ERRORED;
1125
newBoundary.status = CLIENT_RENDERED;
1130
- const thrownInfo = getThrownInfo(request, task.componentStack);
1126
+ const thrownInfo = getThrownInfo(task.componentStack);
1127
let errorDigest;
1128
if (
1129
enablePostpone &&
1269
}
1270
} catch (error: mixed) {
1271
resumedBoundary.status = CLIENT_RENDERED;
1276
- const thrownInfo = getThrownInfo(request, task.componentStack);
1272
+ const thrownInfo = getThrownInfo(task.componentStack);
1273
let errorDigest;
1274
if (
1275
enablePostpone &&
2333
// in the original prerender. What's unable to complete is the child
2334
// replay nodes which might be Suspense boundaries which are able to
2335
// absorb the error and we can still continue with siblings.
2340
- const thrownInfo = getThrownInfo(request, task.componentStack);
2336
+ const thrownInfo = getThrownInfo(task.componentStack);
2337
erroredReplay(
2338
request,
2339
task.blockedBoundary,
2864
// replay nodes which might be Suspense boundaries which are able to
2865
// absorb the error and we can still continue with siblings.
2866
// This is an error, stash the component stack if it is null.
2871
- const thrownInfo = getThrownInfo(request, task.componentStack);
2867
+ const thrownInfo = getThrownInfo(task.componentStack);
2868
erroredReplay(
2869
request,
2870
task.blockedBoundary,
3463
const trackedPostpones = request.trackedPostpones;
3464
3465
const postponeInstance: Postpone = (x: any);
3470
- const thrownInfo = getThrownInfo(request, task.componentStack);
3466
+ const thrownInfo = getThrownInfo(task.componentStack);
3467
const postponedSegment = injectPostponedHole(
3468
request,
3469
((task: any): RenderTask), // We don't use ReplayTasks in prerenders.
3778
boundary.status = CLIENT_RENDERED;
3779
// We construct an errorInfo from the boundary's componentStack so the error in dev will indicate which
3780
// boundary the message is referring to
3785
- const errorInfo = getThrownInfo(request, task.componentStack);
3781
+ const errorInfo = getThrownInfo(task.componentStack);
3782
let errorDigest;
3783
if (
3784
enablePostpone &&
4070
task.abortSet.delete(task);
4071
const postponeInstance: Postpone = (x: any);
4072
4077
- const postponeInfo = getThrownInfo(request, task.componentStack);
4073
+ const postponeInfo = getThrownInfo(task.componentStack);
4074
logPostpone(request, postponeInstance.message, postponeInfo);
4075
trackPostpone(request, trackedPostpones, task, segment);
4076
finishedTask(request, task.blockedBoundary, segment);
4078
}
4079
}
4080
4085
- const errorInfo = getThrownInfo(request, task.componentStack);
4081
+ const errorInfo = getThrownInfo(task.componentStack);
4082
task.abortSet.delete(task);
4083
segment.status = ERRORED;
4084
erroredTask(request, task.blockedBoundary, x, errorInfo);
4152
}
4153
task.replay.pendingTasks--;
4154
task.abortSet.delete(task);
4159
- const errorInfo = getThrownInfo(request, task.componentStack);
4155
+ const errorInfo = getThrownInfo(task.componentStack);
4156
erroredReplay(
4157
request,
4158
task.blockedBoundary,