Skip to content

Commit 14b92e6

Browse files
authored
fix: log the error instance modified extra location info (#71930)
1 parent b2bc1ed commit 14b92e6

File tree

2 files changed

+32
-35
lines changed

2 files changed

+32
-35
lines changed

packages/next/src/client/react-client-callbacks/app-router.ts

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { handleClientError } from '../components/react-dev-overlay/internal/help
66
import { isNextRouterError } from '../components/is-next-router-error'
77
import { isBailoutToCSRError } from '../../shared/lib/lazy-dynamic/bailout-to-csr'
88
import { reportGlobalError } from './report-global-error'
9-
import isError from '../../lib/is-error'
109
import { originConsoleError } from '../components/globals/intercept-console-error'
1110

1211
export const onCaughtError: HydrationOptions['onCaughtError'] = (
@@ -16,9 +15,7 @@ export const onCaughtError: HydrationOptions['onCaughtError'] = (
1615
// Skip certain custom errors which are not expected to be reported on client
1716
if (isBailoutToCSRError(err) || isNextRouterError(err)) return
1817

19-
const stitchedError = getReactStitchedError(err)
20-
21-
if (process.env.NODE_ENV === 'development') {
18+
if (process.env.NODE_ENV !== 'production') {
2219
const errorBoundaryComponent = errorInfo?.errorBoundary?.constructor
2320
const errorBoundaryName =
2421
// read react component displayName
@@ -36,11 +33,6 @@ export const onCaughtError: HydrationOptions['onCaughtError'] = (
3633
componentThatErroredFrame?.match(/\s+at (\w+)\s+|(\w+)@/) ?? []
3734
const componentThatErroredName = matches[1] || matches[2] || 'Unknown'
3835

39-
// In development mode, pass along the component stack to the error
40-
if (process.env.NODE_ENV === 'development' && errorInfo.componentStack) {
41-
;(stitchedError as any)._componentStack = errorInfo.componentStack
42-
}
43-
4436
// Create error location with errored component and error boundary, to match the behavior of default React onCaughtError handler.
4537
const errorBoundaryMessage = `It was handled by the <${errorBoundaryName}> error boundary.`
4638
const componentErrorMessage = componentThatErroredName
@@ -49,10 +41,16 @@ export const onCaughtError: HydrationOptions['onCaughtError'] = (
4941

5042
const errorLocation = `${componentErrorMessage} ${errorBoundaryMessage}`
5143

52-
const originErrorStack = isError(err) ? err.stack || '' : ''
44+
const stitchedError = getReactStitchedError(err)
45+
// TODO: change to passing down errorInfo later
46+
// In development mode, pass along the component stack to the error
47+
if (errorInfo.componentStack) {
48+
;(stitchedError as any)._componentStack = errorInfo.componentStack
49+
}
50+
51+
// Log and report the error with location but without modifying the error stack
52+
originConsoleError('%o\n\n%s', err, errorLocation)
5353

54-
// Log the modified error message with stack so without being intercepted again.
55-
originConsoleError(originErrorStack + '\n\n' + errorLocation)
5654
handleClientError(stitchedError, [])
5755
} else {
5856
originConsoleError(err)
@@ -66,29 +64,28 @@ export const onUncaughtError: HydrationOptions['onUncaughtError'] = (
6664
// Skip certain custom errors which are not expected to be reported on client
6765
if (isBailoutToCSRError(err) || isNextRouterError(err)) return
6866

69-
const stitchedError = getReactStitchedError(err)
70-
71-
if (process.env.NODE_ENV === 'development') {
67+
if (process.env.NODE_ENV !== 'production') {
7268
const componentThatErroredFrame = errorInfo?.componentStack?.split('\n')[1]
7369

7470
// Match chrome or safari stack trace
7571
const matches =
7672
componentThatErroredFrame?.match(/\s+at (\w+)\s+|(\w+)@/) ?? []
7773
const componentThatErroredName = matches[1] || matches[2] || 'Unknown'
7874

79-
// In development mode, pass along the component stack to the error
80-
if (process.env.NODE_ENV === 'development' && errorInfo.componentStack) {
81-
;(stitchedError as any)._componentStack = errorInfo.componentStack
82-
}
83-
8475
// Create error location with errored component and error boundary, to match the behavior of default React onCaughtError handler.
8576
const errorLocation = componentThatErroredName
8677
? `The above error occurred in the <${componentThatErroredName}> component.`
8778
: `The above error occurred in one of your components.`
8879

89-
const errStack = (stitchedError as any).stack || ''
90-
// Log the modified error message with stack so without being intercepted again.
91-
originConsoleError(errStack + '\n\n' + errorLocation)
80+
const stitchedError = getReactStitchedError(err)
81+
// TODO: change to passing down errorInfo later
82+
// In development mode, pass along the component stack to the error
83+
if (errorInfo.componentStack) {
84+
;(stitchedError as any)._componentStack = errorInfo.componentStack
85+
}
86+
87+
// Log and report the error with location but without modifying the error stack
88+
originConsoleError('%o\n\n%s', err, errorLocation)
9289
reportGlobalError(stitchedError)
9390
} else {
9491
reportGlobalError(err)

test/development/app-dir/owner-stack/owner-stack.test.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ describe('app-dir - owner-stack', () => {
7474

7575
if (process.env.TURBOPACK) {
7676
expect(normalizeStackTrace(errorLog)).toMatchInlineSnapshot(`
77-
"Error: browser error
77+
"%o
78+
%s Error: browser error
7879
at useThrowError
7980
at useErrorHook
8081
at Page
@@ -88,12 +89,12 @@ describe('app-dir - owner-stack', () => {
8889
at renderRootSync
8990
at performWorkOnRoot
9091
at performWorkOnRootViaSchedulerTask
91-
at MessagePort.performWorkUntilDeadline
92-
The above error occurred in the <Page> component. It was handled by the <ReactDevOverlay> error boundary."
92+
at MessagePort.performWorkUntilDeadline The above error occurred in the <Page> component. It was handled by the <ReactDevOverlay> error boundary."
9393
`)
9494
} else {
9595
expect(normalizeStackTrace(errorLog)).toMatchInlineSnapshot(`
96-
"Error: browser error
96+
"%o
97+
%s Error: browser error
9798
at useThrowError
9899
at useErrorHook
99100
at Page
@@ -107,8 +108,7 @@ describe('app-dir - owner-stack', () => {
107108
at renderRootSync
108109
at performWorkOnRoot
109110
at performWorkOnRootViaSchedulerTask
110-
at MessagePort.performWorkUntilDeadline
111-
The above error occurred in the <Page> component. It was handled by the <ReactDevOverlay> error boundary."
111+
at MessagePort.performWorkUntilDeadline The above error occurred in the <Page> component. It was handled by the <ReactDevOverlay> error boundary."
112112
`)
113113
}
114114
})
@@ -144,7 +144,8 @@ describe('app-dir - owner-stack', () => {
144144
}
145145

146146
expect(normalizeStackTrace(errorLog)).toMatchInlineSnapshot(`
147-
"Error: browser error
147+
"%o
148+
%s Error: browser error
148149
at useThrowError
149150
at useErrorHook
150151
at Thrower
@@ -158,8 +159,7 @@ describe('app-dir - owner-stack', () => {
158159
at renderRootSync
159160
at performWorkOnRoot
160161
at performWorkOnRootViaSchedulerTask
161-
at MessagePort.performWorkUntilDeadline
162-
The above error occurred in the <Thrower> component. It was handled by the <MyErrorBoundary> error boundary."
162+
at MessagePort.performWorkUntilDeadline The above error occurred in the <Thrower> component. It was handled by the <MyErrorBoundary> error boundary."
163163
`)
164164
})
165165

@@ -187,7 +187,8 @@ describe('app-dir - owner-stack', () => {
187187
}).message
188188

189189
expect(normalizeStackTrace(errorLog)).toMatchInlineSnapshot(`
190-
"Error: ssr error
190+
"%o
191+
%s Error: ssr error
191192
at useThrowError
192193
at useErrorHook
193194
at Page
@@ -201,8 +202,7 @@ describe('app-dir - owner-stack', () => {
201202
at renderRootSync
202203
at performWorkOnRoot
203204
at performWorkOnRootViaSchedulerTask
204-
at MessagePort.performWorkUntilDeadline
205-
The above error occurred in the <Page> component. It was handled by the <ReactDevOverlay> error boundary."
205+
at MessagePort.performWorkUntilDeadline The above error occurred in the <Page> component. It was handled by the <ReactDevOverlay> error boundary."
206206
`)
207207
})
208208

0 commit comments

Comments
 (0)