-
Notifications
You must be signed in to change notification settings - Fork 47k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Fizz] Client render the nearest child or parent suspense boundary if replay errors or is aborted #27386
Conversation
The idea for this check is that we shouldn't flush anything before we flush the shell. That may or may not hold true in future formats like RN. It is a problem for resuming because with resuming it's possible to have root tasks that are used from resuming but the shell was already flushed so we can have completed boundaries before the shell has fully resumed. It's not technically necessary to bail early because there won't be anything in partialBoundaries or completedBoundaries because nothing gets added there unless the parent has already flushed. It's not exactly slow to have to check the length of three arrays so it's probably not a big deal. Flush partials in an early preamble needs further consideration regardless.
Also properly set keyPath
…boundaries Typically aborting or erroring a replaying boundary will just client render it like normal. However, when it happens at the shell level, we might not have discovered all the boundaries since we didn't replay down to them. So we need to go find any remaining boundaries and trigger a client render instruction for them. We also shouldn't trigger a fatalError in these scenarios since it's not fatal. We've already emitted the shell.
We shouldn't log an extra error for the shell itself. Only the errored boundaries. Since we only replay paths down to resumable boundaries there should be at least one that gets the log.
); | ||
// If we're replaying through this pass, it means we're replaying through | ||
// an already completed Suspense boundary. It's too late to do anything about it | ||
// so we can just render through it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not directly related to this PR but surfaced by the test cases.
Completed Suspense boundaries can be parents that we replay through but since they're already complete they don't add any features. It's just the same as if it's in the shell. All of it has already flushed.
That's because if the child of the replay is a Suspense boundary we can client there instead instead of the parent boundary. For the shell, that will always be the case.
e2963e3
to
65c7519
Compare
… replay errors or is aborted (#27386) Based on #27385. When we error or abort during replay, that doesn't actually error the component that errored because that has already rendered. The error only affects any child that is not yet completed. Therefore the error kind of gets thrown at the resumable point. The resumable point might be a hole in the replay path, in which case throwing there errors the parent boundary just the same as if the replay component errored. If the hole is inside a deeper Suspense boundary though, then it's that Suspense boundary that gets client rendered. I.e. the child boundary. We can still finish any siblings. In the shell all resumable points are inside a boundary since we must have finished the shell. Therefore if you error in the root, we just simply just turn all incomplete boundaries into client renders. DiffTrain build for [925c66a](925c66a)
if (resumedBoundary.parentFlushed) { | ||
request.clientRenderedBoundaries.push(resumedBoundary); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we know the parent flushed in this case already
Update React from d6dcad6a8 to 2807d781a. ### React upstream changes - facebook/react#27387 - facebook/react#27386 - facebook/react#27385 - facebook/react#27379 - facebook/react#27382 Closes NEXT-1637
… replay errors or is aborted (facebook#27386) Based on facebook#27385. When we error or abort during replay, that doesn't actually error the component that errored because that has already rendered. The error only affects any child that is not yet completed. Therefore the error kind of gets thrown at the resumable point. The resumable point might be a hole in the replay path, in which case throwing there errors the parent boundary just the same as if the replay component errored. If the hole is inside a deeper Suspense boundary though, then it's that Suspense boundary that gets client rendered. I.e. the child boundary. We can still finish any siblings. In the shell all resumable points are inside a boundary since we must have finished the shell. Therefore if you error in the root, we just simply just turn all incomplete boundaries into client renders.
… replay errors or is aborted (#27386) Based on #27385. When we error or abort during replay, that doesn't actually error the component that errored because that has already rendered. The error only affects any child that is not yet completed. Therefore the error kind of gets thrown at the resumable point. The resumable point might be a hole in the replay path, in which case throwing there errors the parent boundary just the same as if the replay component errored. If the hole is inside a deeper Suspense boundary though, then it's that Suspense boundary that gets client rendered. I.e. the child boundary. We can still finish any siblings. In the shell all resumable points are inside a boundary since we must have finished the shell. Therefore if you error in the root, we just simply just turn all incomplete boundaries into client renders. DiffTrain build for commit 925c66a.
Based on #27385.
When we error or abort during replay, that doesn't actually error the component that errored because that has already rendered. The error only affects any child that is not yet completed. Therefore the error kind of gets thrown at the resumable point.
The resumable point might be a hole in the replay path, in which case throwing there errors the parent boundary just the same as if the replay component errored. If the hole is inside a deeper Suspense boundary though, then it's that Suspense boundary that gets client rendered. I.e. the child boundary. We can still finish any siblings.
In the shell all resumable points are inside a boundary since we must have finished the shell. Therefore if you error in the root, we just simply just turn all incomplete boundaries into client renders.