Skip to content

Commit 94b4aa6

Browse files
committed
[dev-overlay] Inject get*Stack implementation
The stitched-errors module will live in a different layer than the app dev-overlay. In that future we need to pass the `get*Stack` implementations to the dev-overlay. Right now it's not meaningful but makes future diffs smaller.
1 parent 39380c1 commit 94b4aa6

File tree

3 files changed

+48
-35
lines changed

3 files changed

+48
-35
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import type { DevIndicatorServerState } from '../../../../server/dev/dev-indicat
4444
import reportHmrLatency from '../utils/report-hmr-latency'
4545
import { TurbopackHmr } from '../utils/turbopack-hot-reloader-common'
4646
import { NEXT_HMR_REFRESH_HASH_COOKIE } from '../../app-router-headers'
47+
import { getComponentStack, getOwnerStack } from '../../errors/stitched-error'
4748

4849
export interface Dispatcher {
4950
onBuildOk(): void
@@ -479,7 +480,11 @@ export default function HotReload({
479480
children: ReactNode
480481
globalError: [GlobalErrorComponent, React.ReactNode]
481482
}) {
482-
const [state, dispatch] = useErrorOverlayReducer('app')
483+
const [state, dispatch] = useErrorOverlayReducer(
484+
'app',
485+
getComponentStack,
486+
getOwnerStack
487+
)
483488

484489
const dispatcher = useMemo<Dispatcher>(() => {
485490
return {

packages/next/src/client/components/react-dev-overlay/pages/hooks.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@ import React from 'react'
22
import * as Bus from './bus'
33
import { useErrorOverlayReducer } from '../shared'
44
import { Router } from '../../../router'
5+
import { getComponentStack, getOwnerStack } from '../../errors/stitched-error'
56

67
export const usePagesDevOverlay = () => {
7-
const [state, dispatch] = useErrorOverlayReducer('pages')
8+
const [state, dispatch] = useErrorOverlayReducer(
9+
'pages',
10+
getComponentStack,
11+
getOwnerStack
12+
)
813

914
React.useEffect(() => {
1015
Bus.on(dispatch)

packages/next/src/client/components/react-dev-overlay/shared.ts

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import type { DebugInfo } from './types'
77
import type { DevIndicatorServerState } from '../../../server/dev/dev-indicator-server-state'
88
import type { HMR_ACTION_TYPES } from '../../../server/dev/hot-reloader-types'
99
import { parseStack } from './utils/parse-stack'
10-
import { getComponentStack, getOwnerStack } from '../errors/stitched-error'
1110

1211
type FastRefreshState =
1312
/** No refresh in progress. */
@@ -130,37 +129,6 @@ function getStackIgnoringStrictMode(stack: string | undefined) {
130129
return stack?.split(REACT_ERROR_STACK_BOTTOM_FRAME_REGEX)[0]
131130
}
132131

133-
function pushErrorFilterDuplicates(
134-
events: SupportedErrorEvent[],
135-
id: number,
136-
error: Error
137-
): SupportedErrorEvent[] {
138-
const componentStack = getComponentStack(error)
139-
const componentStackFrames =
140-
componentStack === undefined
141-
? undefined
142-
: parseComponentStack(componentStack)
143-
const frames = parseStack((error.stack || '') + getOwnerStack(error) || '')
144-
const pendingEvent: SupportedErrorEvent = {
145-
id,
146-
error,
147-
frames,
148-
componentStackFrames,
149-
}
150-
const pendingEvents = events.filter((event) => {
151-
// Filter out duplicate errors
152-
return (
153-
(event.error.stack !== pendingEvent.error.stack &&
154-
// TODO: Let ReactDevTools control deduping instead?
155-
getStackIgnoringStrictMode(event.error.stack) !==
156-
getStackIgnoringStrictMode(pendingEvent.error.stack)) ||
157-
getOwnerStack(event.error) !== getOwnerStack(pendingEvent.error)
158-
)
159-
})
160-
pendingEvents.push(pendingEvent)
161-
return pendingEvents
162-
}
163-
164132
const shouldDisableDevIndicator =
165133
process.env.__NEXT_DEV_INDICATOR?.toString() === 'false'
166134

@@ -198,7 +166,42 @@ function getInitialState(
198166
}
199167
}
200168

201-
export function useErrorOverlayReducer(routerType: 'pages' | 'app') {
169+
export function useErrorOverlayReducer(
170+
routerType: 'pages' | 'app',
171+
getComponentStack: (error: Error) => string | undefined,
172+
getOwnerStack: (error: Error) => string | null | undefined
173+
) {
174+
function pushErrorFilterDuplicates(
175+
events: SupportedErrorEvent[],
176+
id: number,
177+
error: Error
178+
): SupportedErrorEvent[] {
179+
const componentStack = getComponentStack(error)
180+
const componentStackFrames =
181+
componentStack === undefined
182+
? undefined
183+
: parseComponentStack(componentStack)
184+
const frames = parseStack((error.stack || '') + getOwnerStack(error) || '')
185+
const pendingEvent: SupportedErrorEvent = {
186+
id,
187+
error,
188+
frames,
189+
componentStackFrames,
190+
}
191+
const pendingEvents = events.filter((event) => {
192+
// Filter out duplicate errors
193+
return (
194+
(event.error.stack !== pendingEvent.error.stack &&
195+
// TODO: Let ReactDevTools control deduping instead?
196+
getStackIgnoringStrictMode(event.error.stack) !==
197+
getStackIgnoringStrictMode(pendingEvent.error.stack)) ||
198+
getOwnerStack(event.error) !== getOwnerStack(pendingEvent.error)
199+
)
200+
})
201+
pendingEvents.push(pendingEvent)
202+
return pendingEvents
203+
}
204+
202205
return useReducer((state: OverlayState, action: BusEvent): OverlayState => {
203206
switch (action.type) {
204207
case ACTION_DEBUG_INFO: {

0 commit comments

Comments
 (0)