Skip to content

Commit

Permalink
[Fizz] track postpones when aborting boundaries with a postpone
Browse files Browse the repository at this point in the history
When aborting with a postpone value boundaries are put into client rendered mode even during prerenders. This doesn't follow the postpoen semantics of the rest of fizz where during a prerender a postpone is tracked and it will leave holes in tracked postpone state that can be resumed. This change updates this behavior to match the postpones semantics between aborts and imperative postpones.
  • Loading branch information
gnoff committed Aug 20, 2024
1 parent a960b92 commit b7f6c17
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7727,7 +7727,6 @@ describe('ReactDOMFizzServer', () => {

const prerendered = await pendingPrerender;

expect(prerendered.postponed).toBe(null);
expect(errors).toEqual([]);
expect(postpones).toEqual(['manufactured', 'manufactured']);

Expand Down
14 changes: 13 additions & 1 deletion packages/react-server/src/ReactFizzServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3857,7 +3857,6 @@ function abortTask(task: Task, request: Request, error: mixed): void {
} else {
boundary.pendingTasks--;
if (boundary.status !== CLIENT_RENDERED) {
boundary.status = CLIENT_RENDERED;
// We construct an errorInfo from the boundary's componentStack so the error in dev will indicate which
// boundary the message is referring to
const errorInfo = getThrownInfo(task.componentStack);
Expand All @@ -3870,11 +3869,24 @@ function abortTask(task: Task, request: Request, error: mixed): void {
) {
const postponeInstance: Postpone = (error: any);
logPostpone(request, postponeInstance.message, errorInfo, null);
if (request.trackedPostpones !== null && segment !== null) {
trackPostpone(request, request.trackedPostpones, task, segment);
finishedTask(request, task.blockedBoundary, segment);

// If this boundary was still pending then we haven't already cancelled its fallbacks.
// We'll need to abort the fallbacks, which will also error that parent boundary.
boundary.fallbackAbortableTasks.forEach(fallbackTask =>
abortTask(fallbackTask, request, error),
);
boundary.fallbackAbortableTasks.clear();
return;
}
// TODO: Figure out a better signal than a magic digest value.
errorDigest = 'POSTPONE';
} else {
errorDigest = logRecoverableError(request, error, errorInfo, null);
}
boundary.status = CLIENT_RENDERED;
encodeErrorForBoundary(boundary, errorDigest, error, errorInfo, true);

untrackBoundary(request, boundary);
Expand Down

0 comments on commit b7f6c17

Please sign in to comment.