Skip to content

Commit

Permalink
share the hydration error info extraction util
Browse files Browse the repository at this point in the history
  • Loading branch information
huozhi committed Jul 10, 2024
1 parent 3f47c94 commit ea8ccee
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,7 @@ const rejectionQueue: Array<Error> = []
const errorHandlers: Array<ErrorHandler> = []
const rejectionHandlers: Array<ErrorHandler> = []

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(
Expand Down Expand Up @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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
Expand All @@ -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 =
Expand All @@ -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,
})
}
Expand Down

0 comments on commit ea8ccee

Please # to comment.