Surface invalid dynamic usage errors via Flight in dev#93706
Open
unstubbable wants to merge 9 commits intocanaryfrom
Open
Surface invalid dynamic usage errors via Flight in dev#93706unstubbable wants to merge 9 commits intocanaryfrom
unstubbable wants to merge 9 commits intocanaryfrom
Conversation
When a `'use cache'` recorded an invalid dynamic usage error on the work store (for example a `cookies()` call inside `'use cache'`, a nested-dynamic `cacheLife`, or a `'use cache'` fill timeout), `renderToHTMLOrFlight` used to throw the recorded error right after `renderToStream` returned. The throw bubbled up through `base-server` and ended up rendering the Pages-Router `/_error` page, which felt out of place in an app-router context. This change removes that throw, so the error reaches the dev overlay through the same Flight channel that already surfaces static-shell-validation and instant-validation errors — `logMessagesAndSendErrorsToBrowser`, called from `spawnStaticShellValidationInDev` and from the validation-skipped fallback in `generateDynamicFlightRenderResultWithStagesInDev`. The original motivation for the throw was to avoid double-logging in the uncaught case. Without it, both React's `serverComponentsErrorHandler` (which stamps a digest and emits a Flight error chunk) and `logMessagesAndSendErrorsToBrowser` would forward the same error. We now dedupe by skipping the `logMessagesAndSendErrorsToBrowser` call whenever the recorded error already carries a `digest`, since that is exactly the signal that React has already seen it. Caught cases (no `digest`) continue to surface through `logMessagesAndSendErrorsToBrowser` as a collapsed dev-overlay entry; uncaught cases surface via React's Flight error chunk as an auto-opened redbox. This also sets us up for the upstack PR that attaches the inner cache call site as `cause` of the nested-dynamic prerender error. With errors now travelling uniformly over Flight — which preserves `cause` natively — the cause flows straight through to the dev overlay without needing to serialize it into the error page.
Contributor
Author
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Contributor
Tests PassedCommit: 6d90d31 |
Contributor
Stats from current PR✅ No significant changes detected📊 All Metrics📖 Metrics GlossaryDev Server Metrics:
Build Metrics:
Change Thresholds:
⚡ Dev Server
📦 Dev Server (Webpack) (Legacy)📦 Dev Server (Webpack)
⚡ Production Builds
📦 Production Builds (Webpack) (Legacy)📦 Production Builds (Webpack)
📦 Bundle SizesBundle Sizes⚡ TurbopackClient Main Bundles
Server Middleware
Build DetailsBuild Manifests
📦 WebpackClient Main Bundles
Polyfills
Pages
Server Edge SSR
Middleware
Build DetailsBuild Manifests
Build Cache
🔄 Shared (bundler-independent)Runtimes
📝 Changed Files (8 files)Files with changes:
View diffsapp-page-exp..ntime.dev.jsfailed to diffapp-page-exp..time.prod.jsDiff too large to display app-page-tur..ntime.dev.jsfailed to diffapp-page-tur..time.prod.jsDiff too large to display app-page-tur..ntime.dev.jsfailed to diffapp-page-tur..time.prod.jsDiff too large to display app-page.runtime.dev.jsfailed to diffapp-page.runtime.prod.jsDiff too large to display 📎 Tarball URLCommit: bbf3e07 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.

When a
'use cache'recorded an invalid dynamic usage error on the work store (for example acookies()call inside'use cache', a nested-dynamiccacheLife, or a'use cache'fill timeout),renderToHTMLOrFlightused to throw the recorded error right afterrenderToStreamreturned. The throw bubbled up throughbase-serverand ended up rendering the Pages-Router/_errorpage, which felt out of place in an app-router context. This change removes that throw, so the error reaches the dev overlay through the same Flight channel that already surfaces static-shell-validation and instant-validation errors —logMessagesAndSendErrorsToBrowser, called fromspawnStaticShellValidationInDevand from the validation-skipped fallback ingenerateDynamicFlightRenderResultWithStagesInDev.The original motivation for the throw was to avoid double-logging in the uncaught case. Without it, both React's
serverComponentsErrorHandler(which stamps a digest and emits a Flight error chunk) andlogMessagesAndSendErrorsToBrowserwould forward the same error. We now dedupe by skipping thelogMessagesAndSendErrorsToBrowsercall whenever the recorded error already carries adigest, since that is exactly the signal that React has already seen it. Caught cases (nodigest) continue to surface throughlogMessagesAndSendErrorsToBrowseras a collapsed dev-overlay entry; uncaught cases surface via React's Flight error chunk as an auto-opened redbox.This also sets us up for the upstack PR that attaches the inner cache call site as
causeof the nested-dynamic prerender error. With errors now travelling uniformly over Flight — which preservescausenatively — the cause flows straight through to the dev overlay without needing to serialize it into the error page.