fix: handle notFound in Suspense with cacheComponents enabled #87041
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What?
This PR fixes an issue where
notFound()(and other HTTP access fallback errors likeforbidden()/unauthorized()) would cause "Connection closed" errors whencacheComponents: trueis enabled and the page has a Suspense boundary with an async component.Why?
When
cacheComponentsis enabled and a page is prerendered, subsequent requests useDynamicState.DATAmode which only sends RSC data without re-rendering the HTML shell. However, whennotFound()is thrown during this RSC render, the prerendered HTML doesn't contain the not-found component, causing the client to receive an incomplete stream and display "Connection closed" errors.How?
This fix buffers the RSC stream in
DynamicState.DATAmode to detect HTTP access fallback errors. After consuming the stream:reactServerErrorsByDigestfor any errors with theHTTP_ERROR_FALLBACK_ERROR_CODEprefixTest Plan
Added two test cases:
not-found-suspense: TestsnotFound()thrown inside a Suspense boundarynot-found-with-layout-suspense: Exact reproduction of the issue -notFound()in page with async component in layout's SuspenseFixes #86251