fix(dev-overlay): surface attribute-only hydration mismatches as Cons…#2706
Draft
MaxtuneLee wants to merge 3 commits into
Draft
fix(dev-overlay): surface attribute-only hydration mismatches as Cons…#2706MaxtuneLee wants to merge 3 commits into
MaxtuneLee wants to merge 3 commits into
Conversation
…ole Error React 19 reports an attribute-only hydration mismatch through console.error only -- it never calls onRecoverableError and never patches the mismatched attribute. vinext's dev overlay listened to onCaughtError/onUncaughtError, window error/unhandledrejection events, and Vite HMR errors, but not console.error, so this case surfaced nothing in the overlay. - Wire onRecoverableError (devOnRecoverableError) for the first time, so recoverable hydration mismatches (text/element-tree) surface as "Recoverable Error" instead of falling through to the window error listener mislabeled as "Unhandled Script Error". - Patch console.error, narrowly gated: only messages matching React's attribute-only hydration regex open the overlay (as "Console Error"); every other console.error call is left exactly as before. General console.error interception (matching Next.js's broader Console Error behavior for any console.error call) is intentionally out of scope here and continues on a follow-up branch.
commit: |
Contributor
Performance benchmarksCompared 0 improved · 0 regressed · 6 within ±1.5%
View detailed results and traces 🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head |
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.
Problem
Fixes #2705
React 19 reports an attribute-only hydration mismatch through
console.erroronly. vinext's dev overlay listened toonCaughtError/onUncaughtError, windowerror/unhandledrejectionevents, and Vite HMR errors, but notconsole.error, so this case surfaced nothing in the overlay.What changed
onRecoverableError(devOnRecoverableError) for the first time, so recoverable hydration mismatches (text/element-tree) surface asRecoverable Errorinstead of falling through to the window error listener and getting mislabeled asUnhandled Script Error.console.error, only messages matching React's attribute-only hydration regex (isAttributeOnlyHydrationWarningMessageindev-console-error.ts) open the overlay, as a newconsole-errorsource labeledConsole Error. Every otherconsole.errorcall is left exactly as before.dev-error-overlay-store.ts'sreportToOverlay/isSameReportedError): two reports only count as the same failure when message, stack, and React's owner stack (captureOwnerStack(), captured synchronously at report time) all match. This replaces an earlier text-plus-1s-window dedup approach, and this will still keep the same attribute warning from two different components (identical message text) from collapsing into one entry.installDevErrorOverlay()installer: App Router viaapp-browser-entry.ts, Pages Router viapages-dev-hydration.ts/pages-client-entry.ts.Correspondence with Next.js
devOnRecoverableErrormirrorsclient/react-client-callbacks/on-recoverable-error.ts'sonRecoverableError.next-devtools/dev-overlay/shared.tsandstitched-error.ts; vinext stores the owner stack as a plain string field instead of aWeakMap<Error, string>since the overlay store never retains the rawErrorobject.Testing
tests/dev-console-error.test.ts,tests/app-browser-entry.test.ts, all green.tests/e2e/app-router/dev-error-overlay.spec.tsand newtests/e2e/pages-router/dev-overlay-hydration.spec.ts, against new fixtures (tests/fixtures/app-basic/app/dev-overlay-hydration/*,tests/fixtures/pages-basic/pages/dev-overlay-hydration.tsx) reproducing the attribute-only mismatch. All green.