Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 20bc66a

Browse files
committed
[dev-overlay] Remove "Unhandled Runtime Error" label
We already have "Runtime Error" and the distinction between the two is currently pretty obscure. This enables us to cleanup some of the confusing "isUnhandledError" logic that returned true for console errors.
1 parent 5c58751 commit 20bc66a

File tree

28 files changed

+191
-180
lines changed

28 files changed

+191
-180
lines changed

packages/next/src/client/components/errors/console-error.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@ const consoleTypeSym = Symbol.for('next.console.error.type')
44

55
// Represent non Error shape unhandled promise rejections or console.error errors.
66
// Those errors will be captured and displayed in Error Overlay.
7-
type UnhandledError = Error & {
8-
[digestSym]: 'NEXT_UNHANDLED_ERROR'
7+
export type ConsoleError = Error & {
8+
[digestSym]: 'NEXT_CONSOLE_ERROR'
99
[consoleTypeSym]: 'string' | 'error'
1010
environmentName: string
1111
}
1212

13-
export function createUnhandledError(
13+
export function createConsoleError(
1414
message: string | Error,
1515
environmentName?: string | null
16-
): UnhandledError {
16+
): ConsoleError {
1717
const error = (
1818
typeof message === 'string' ? new Error(message) : message
19-
) as UnhandledError
20-
error[digestSym] = 'NEXT_UNHANDLED_ERROR'
19+
) as ConsoleError
20+
error[digestSym] = 'NEXT_CONSOLE_ERROR'
2121
error[consoleTypeSym] = typeof message === 'string' ? 'string' : 'error'
2222

2323
if (environmentName && !error.environmentName) {
@@ -27,12 +27,10 @@ export function createUnhandledError(
2727
return error
2828
}
2929

30-
export const isUnhandledConsoleOrRejection = (
31-
error: any
32-
): error is UnhandledError => {
33-
return error && error[digestSym] === 'NEXT_UNHANDLED_ERROR'
30+
export const isConsoleError = (error: any): error is ConsoleError => {
31+
return error && error[digestSym] === 'NEXT_CONSOLE_ERROR'
3432
}
3533

36-
export const getUnhandledErrorType = (error: UnhandledError) => {
34+
export const getConsoleErrorType = (error: ConsoleError) => {
3735
return error[consoleTypeSym]
3836
}

packages/next/src/client/components/errors/use-error-handler.ts

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { isNextRouterError } from '../is-next-router-error'
44
import { storeHydrationErrorStateFromConsoleArgs } from './hydration-error-info'
55
import { formatConsoleArgs, parseConsoleArgs } from '../../lib/console'
66
import isError from '../../../lib/is-error'
7-
import { createUnhandledError } from './console-error'
7+
import { createConsoleError } from './console-error'
88
import { enqueueConsecutiveDedupedError } from './enqueue-client-error'
99
import { getReactStitchedError } from '../errors/stitched-error'
1010

@@ -18,21 +18,19 @@ const errorHandlers: Array<ErrorHandler> = []
1818
const rejectionQueue: Array<Error> = []
1919
const rejectionHandlers: Array<ErrorHandler> = []
2020

21-
export function handleClientError(
21+
export function handleConsoleError(
2222
originError: unknown,
23-
consoleErrorArgs: any[],
24-
capturedFromConsole: boolean = false
23+
consoleErrorArgs: any[]
2524
) {
2625
let error: Error
27-
if (!originError || !isError(originError)) {
28-
// If it's not an error, format the args into an error
29-
const formattedErrorMessage = formatConsoleArgs(consoleErrorArgs)
30-
const { environmentName } = parseConsoleArgs(consoleErrorArgs)
31-
error = createUnhandledError(formattedErrorMessage, environmentName)
26+
const { environmentName } = parseConsoleArgs(consoleErrorArgs)
27+
if (isError(originError)) {
28+
error = createConsoleError(originError, environmentName)
3229
} else {
33-
error = capturedFromConsole
34-
? createUnhandledError(originError)
35-
: originError
30+
error = createConsoleError(
31+
formatConsoleArgs(consoleErrorArgs),
32+
environmentName
33+
)
3634
}
3735
error = getReactStitchedError(error)
3836

@@ -49,6 +47,29 @@ export function handleClientError(
4947
}
5048
}
5149

50+
export function handleClientError(originError: unknown) {
51+
let error: Error
52+
if (isError(originError)) {
53+
error = originError
54+
} else {
55+
// If it's not an error, format the args into an error
56+
const formattedErrorMessage = originError + ''
57+
error = new Error(formattedErrorMessage)
58+
}
59+
error = getReactStitchedError(error)
60+
61+
attachHydrationErrorState(error)
62+
63+
enqueueConsecutiveDedupedError(errorQueue, error)
64+
for (const handler of errorHandlers) {
65+
// Delayed the error being passed to React Dev Overlay,
66+
// avoid the state being synchronously updated in the component.
67+
queueMicroTask(() => {
68+
handler(error)
69+
})
70+
}
71+
}
72+
5273
export function useErrorHandler(
5374
handleOnUnhandledError: ErrorHandler,
5475
handleOnUnhandledRejection: ErrorHandler
@@ -85,7 +106,7 @@ function onUnhandledError(event: WindowEventMap['error']): void | boolean {
85106
// When there's an error property present, we log the error to error overlay.
86107
// Otherwise we don't do anything as it's not logging in the console either.
87108
if (event.error) {
88-
handleClientError(event.error, [])
109+
handleClientError(event.error)
89110
}
90111
}
91112

@@ -98,7 +119,7 @@ function onUnhandledRejection(ev: WindowEventMap['unhandledrejection']): void {
98119

99120
let error = reason
100121
if (error && !isError(error)) {
101-
error = createUnhandledError(error + '')
122+
error = new Error(error + '')
102123
}
103124

104125
rejectionQueue.push(error)

packages/next/src/client/components/globals/intercept-console-error.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import isError from '../../../lib/is-error'
22
import { isNextRouterError } from '../is-next-router-error'
3-
import { handleClientError } from '../errors/use-error-handler'
3+
import { handleConsoleError } from '../errors/use-error-handler'
44
import { parseConsoleArgs } from '../../lib/console'
55

66
export const originConsoleError = globalThis.console.error
@@ -29,12 +29,11 @@ export function patchConsoleError() {
2929

3030
if (!isNextRouterError(maybeError)) {
3131
if (process.env.NODE_ENV !== 'production') {
32-
handleClientError(
32+
handleConsoleError(
3333
// replayed errors have their own complex format string that should be used,
3434
// but if we pass the error directly, `handleClientError` will ignore it
3535
maybeError,
36-
args,
37-
true
36+
args
3837
)
3938
}
4039

packages/next/src/client/components/react-dev-overlay/app/app-dev-overlay.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function ReplaySsrOnlyErrors({
5555
// TODO(veil): Produces wrong Owner Stack
5656
// TODO(veil): Mark as recoverable error
5757
// TODO(veil): console.error
58-
handleClientError(ssrError, [])
58+
handleClientError(ssrError)
5959

6060
// If it's missing root tags, we can't recover, make it blocking.
6161
if (ssrError.digest === MISSING_ROOT_TAGS_ERROR) {

packages/next/src/client/components/react-dev-overlay/ui/components/errors/error-overlay-layout/error-overlay-layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import { EnvironmentNameLabel } from '../environment-name-label/environment-name
3737
import { useFocusTrap } from '../dev-tools-indicator/utils'
3838
import { Fader } from '../../fader'
3939

40-
interface ErrorOverlayLayoutProps extends ErrorBaseProps {
40+
export interface ErrorOverlayLayoutProps extends ErrorBaseProps {
4141
errorMessage: ErrorMessageType
4242
errorType: ErrorType
4343
children?: React.ReactNode

packages/next/src/client/components/react-dev-overlay/ui/components/errors/error-type-label/error-type-label.stories.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,6 @@ export const ConsoleError: Story = {
3131
},
3232
}
3333

34-
export const UnhandledRuntimeError: Story = {
35-
args: {
36-
errorType: 'Unhandled Runtime Error',
37-
},
38-
}
39-
4034
export const MissingRequiredHTMLTag: Story = {
4135
args: {
4236
errorType: 'Missing Required HTML Tag',

packages/next/src/client/components/react-dev-overlay/ui/components/errors/error-type-label/error-type-label.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ export type ErrorType =
22
| 'Build Error'
33
| 'Runtime Error'
44
| 'Console Error'
5-
| 'Unhandled Runtime Error'
65
| 'Missing Required HTML Tag'
76

87
type ErrorTypeLabelProps = {

packages/next/src/client/components/react-dev-overlay/ui/container/errors.tsx

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@ import {
1010
getHydrationWarningType,
1111
} from '../../../errors/hydration-error-info'
1212
import {
13-
getUnhandledErrorType,
14-
isUnhandledConsoleOrRejection,
13+
isConsoleError,
14+
getConsoleErrorType,
1515
} from '../../../errors/console-error'
1616
import { extractNextErrorCode } from '../../../../../lib/error-telemetry-utils'
17-
import { ErrorOverlayLayout } from '../components/errors/error-overlay-layout/error-overlay-layout'
17+
import {
18+
ErrorOverlayLayout,
19+
type ErrorOverlayLayoutProps,
20+
} from '../components/errors/error-overlay-layout/error-overlay-layout'
1821
import { NEXTJS_HYDRATION_ERROR_LINK } from '../../../is-hydration-error'
1922
import type { ReadyRuntimeError } from '../../utils/get-error-by-type'
2023
import type { ErrorBaseProps } from '../components/errors/error-overlay/error-overlay'
@@ -38,20 +41,16 @@ function ErrorDescription({
3841
error: Error
3942
hydrationWarning: string | null
4043
}) {
41-
const isUnhandledOrReplayError = isUnhandledConsoleOrRejection(error)
42-
const unhandledErrorType = isUnhandledOrReplayError
43-
? getUnhandledErrorType(error)
44+
const unhandledErrorType = isConsoleError(error)
45+
? getConsoleErrorType(error)
4446
: null
4547
const isConsoleErrorStringMessage = unhandledErrorType === 'string'
4648
// If the error is:
4749
// - hydration warning
4850
// - captured console error or unhandled rejection
4951
// skip displaying the error name
5052
const title =
51-
(isUnhandledOrReplayError && isConsoleErrorStringMessage) ||
52-
hydrationWarning
53-
? ''
54-
: error.name + ': '
53+
isConsoleErrorStringMessage || hydrationWarning ? '' : error.name + ': '
5554

5655
const environmentName =
5756
'environmentName' in error ? error.environmentName : ''
@@ -75,6 +74,13 @@ function ErrorDescription({
7574
)
7675
}
7776

77+
function getErrorType(error: Error): ErrorOverlayLayoutProps['errorType'] {
78+
if (isConsoleError(error)) {
79+
return 'Console Error'
80+
}
81+
return 'Runtime Error'
82+
}
83+
7884
export function Errors({
7985
runtimeErrors,
8086
debugInfo,
@@ -119,7 +125,7 @@ export function Errors({
119125
const isServerError = ['server', 'edge-server'].includes(
120126
getErrorSource(error) || ''
121127
)
122-
const isUnhandledError = isUnhandledConsoleOrRejection(error)
128+
const errorType = getErrorType(error)
123129
const errorDetails: HydrationErrorState = (error as any).details || {}
124130
const notes = errorDetails.notes || ''
125131
const [warningTemplate, serverContent, clientContent] =
@@ -145,13 +151,7 @@ export function Errors({
145151
return (
146152
<ErrorOverlayLayout
147153
errorCode={errorCode}
148-
errorType={
149-
isServerError
150-
? 'Runtime Error'
151-
: isUnhandledError
152-
? 'Console Error'
153-
: 'Unhandled Runtime Error'
154-
}
154+
errorType={errorType}
155155
errorMessage={
156156
<ErrorDescription error={error} hydrationWarning={hydrationWarning} />
157157
}

packages/next/src/client/react-client-callbacks/error-boundary-callbacks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export function onCaughtError(
7979
// Log and report the error with location but without modifying the error stack
8080
originConsoleError('%o\n\n%s', err, errorLocation)
8181

82-
handleClientError(stitchedError, [])
82+
handleClientError(stitchedError)
8383
} else {
8484
originConsoleError(err)
8585
}

0 commit comments

Comments
 (0)