Skip to content

Commit 1b1ee33

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 7ed719f commit 1b1ee33

File tree

3 files changed

+49
-36
lines changed

3 files changed

+49
-36
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: 37 additions & 34 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,38 +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 ownerStack = getOwnerStack(error)
144-
const frames = parseStack((error.stack || '') + (ownerStack || ''))
145-
const pendingEvent: SupportedErrorEvent = {
146-
id,
147-
error,
148-
frames,
149-
componentStackFrames,
150-
}
151-
const pendingEvents = events.filter((event) => {
152-
// Filter out duplicate errors
153-
return (
154-
(event.error.stack !== pendingEvent.error.stack &&
155-
// TODO: Let ReactDevTools control deduping instead?
156-
getStackIgnoringStrictMode(event.error.stack) !==
157-
getStackIgnoringStrictMode(pendingEvent.error.stack)) ||
158-
getOwnerStack(event.error) !== getOwnerStack(pendingEvent.error)
159-
)
160-
})
161-
pendingEvents.push(pendingEvent)
162-
return pendingEvents
163-
}
164-
165132
const shouldDisableDevIndicator =
166133
process.env.__NEXT_DEV_INDICATOR?.toString() === 'false'
167134

@@ -199,7 +166,43 @@ function getInitialState(
199166
}
200167
}
201168

202-
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 ownerStack = getOwnerStack(error)
185+
const frames = parseStack((error.stack || '') + (ownerStack || ''))
186+
const pendingEvent: SupportedErrorEvent = {
187+
id,
188+
error,
189+
frames,
190+
componentStackFrames,
191+
}
192+
const pendingEvents = events.filter((event) => {
193+
// Filter out duplicate errors
194+
return (
195+
(event.error.stack !== pendingEvent.error.stack &&
196+
// TODO: Let ReactDevTools control deduping instead?
197+
getStackIgnoringStrictMode(event.error.stack) !==
198+
getStackIgnoringStrictMode(pendingEvent.error.stack)) ||
199+
getOwnerStack(event.error) !== getOwnerStack(pendingEvent.error)
200+
)
201+
})
202+
pendingEvents.push(pendingEvent)
203+
return pendingEvents
204+
}
205+
203206
return useReducer((state: OverlayState, action: BusEvent): OverlayState => {
204207
switch (action.type) {
205208
case ACTION_DEBUG_INFO: {

0 commit comments

Comments
 (0)