From ea8cceed057532bef518df59d711b27163b172a7 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 10 Jul 2024 20:11:00 +0200 Subject: [PATCH] share the hydration error info extraction util --- .../internal/helpers/use-error-handler.ts | 21 +++++--- .../react-dev-overlay/pages/client.ts | 50 +++---------------- 2 files changed, 20 insertions(+), 51 deletions(-) diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts b/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts index 84bc800417aa8d..a2d9fb81d82658 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts +++ b/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts @@ -24,13 +24,7 @@ const rejectionQueue: Array = [] const errorHandlers: Array = [] const rejectionHandlers: Array = [] -export function handleClientError(error: unknown) { - if (!error || !(error instanceof Error) || typeof error.stack !== 'string') { - // A non-error was thrown, we don't have anything to show. :-( - return - } - - const isCausedByHydrationFailure = isHydrationError(error) +export function attachHydrationErrorState(error: Error) { if ( isHydrationError(error) && !error.message.includes( @@ -69,8 +63,19 @@ export function handleClientError(error: unknown) { ;(error as any).details = parsedHydrationErrorState } + return error +} + +export function handleClientError(error: unknown) { + if (!error || !(error instanceof Error) || typeof error.stack !== 'string') { + // A non-error was thrown, we don't have anything to show. :-( + return + } + + attachHydrationErrorState(error) + // Only queue one hydration every time - if (isCausedByHydrationFailure) { + if (isHydrationError(error)) { if (!hasHydrationError) { errorQueue.push(error) } diff --git a/packages/next/src/client/components/react-dev-overlay/pages/client.ts b/packages/next/src/client/components/react-dev-overlay/pages/client.ts index ad6293c2bd7614..eb32eef108b9ec 100644 --- a/packages/next/src/client/components/react-dev-overlay/pages/client.ts +++ b/packages/next/src/client/components/react-dev-overlay/pages/client.ts @@ -2,7 +2,6 @@ import * as Bus from './bus' import { parseStack } from '../internal/helpers/parseStack' import { parseComponentStack } from '../internal/helpers/parse-component-stack' import { - getReactHydrationDiffSegments, hydrationErrorState, storeHydrationErrorStateFromConsoleArgs, } from '../internal/helpers/hydration-error-info' @@ -16,10 +15,7 @@ import { ACTION_VERSION_INFO, } from '../shared' import type { VersionInfo } from '../../../../server/dev/parse-version-info' -import { - getDefaultHydrationErrorMessage, - isHydrationError, -} from '../../is-hydration-error' +import { attachHydrationErrorState } from '../internal/helpers/use-error-handler' let isRegistered = false let stackTraceLimit: number | undefined = undefined @@ -30,43 +26,8 @@ function handleError(error: unknown) { return } - if ( - isHydrationError(error) && - !error.message.includes( - 'https://nextjs.org/docs/messages/react-hydration-error' - ) - ) { - const reactHydrationDiffSegments = getReactHydrationDiffSegments( - error.message - ) - let parsedHydrationErrorState: typeof hydrationErrorState = {} - if (reactHydrationDiffSegments) { - parsedHydrationErrorState = { - ...(error as any).details, - warning: hydrationErrorState.warning || [ - getDefaultHydrationErrorMessage(), - ], - notes: reactHydrationDiffSegments[0], - reactOutputComponentDiff: reactHydrationDiffSegments[1], - } - } else { - // If there's any extra information in the error message to display, - // append it to the error message details property - if (hydrationErrorState.warning) { - // The patched console.error found hydration errors logged by React - // Append the logged warning to the error message - parsedHydrationErrorState = { - ...(error as any).details, - // It contains the warning, component stack, server and client tag names - ...hydrationErrorState, - } - } - error.message += `\nSee more info here: https://nextjs.org/docs/messages/react-hydration-error` - } - ;(error as any).details = parsedHydrationErrorState - } + attachHydrationErrorState(error) - const e = error const componentStackTrace = (error as any)._componentStack || hydrationErrorState.componentStack const componentStackFrames = @@ -76,11 +37,14 @@ function handleError(error: unknown) { // Skip ModuleBuildError and ModuleNotFoundError, as it will be sent through onBuildError callback. // This is to avoid same error as different type showing up on client to cause flashing. - if (e.name !== 'ModuleBuildError' && e.name !== 'ModuleNotFoundError') { + if ( + error.name !== 'ModuleBuildError' && + error.name !== 'ModuleNotFoundError' + ) { Bus.emit({ type: ACTION_UNHANDLED_ERROR, reason: error, - frames: parseStack(e.stack!), + frames: parseStack(error.stack!), componentStackFrames, }) }