1
- import { Suspense , useMemo , useState } from 'react'
1
+ import { Suspense , useMemo } from 'react'
2
2
import {
3
3
GenericErrorDescription ,
4
- getErrorTypeLabel ,
5
4
HydrationErrorDescription ,
6
- useErrorDetails ,
7
5
} from '../../../../container/errors'
8
6
import { EnvironmentNameLabel } from '../../../errors/environment-name-label/environment-name-label'
9
7
import { ErrorMessage } from '../../../errors/error-message/error-message'
@@ -15,7 +13,6 @@ import {
15
13
} from '../../../../utils/get-error-by-type'
16
14
import type { HydrationErrorState } from '../../../../../shared/hydration-error'
17
15
import type { OverlayState } from '../../../../shared'
18
- import { extractNextErrorCode } from '../../../../../../lib/error-telemetry-utils'
19
16
import { css } from '../../../../utils/css'
20
17
import { getFrameSource } from '../../../../../shared/stack-frame'
21
18
import { Terminal } from '../../../terminal'
@@ -24,6 +21,7 @@ import { NEXTJS_HYDRATION_ERROR_LINK } from '../../../../../shared/react-19-hydr
24
21
import { PseudoHtmlDiff } from '../../../../container/runtime-error/component-stack-pseudo-html'
25
22
import { CodeFrame } from '../../../code-frame/code-frame'
26
23
import { CallStack } from '../../../call-stack/call-stack'
24
+ import { useRuntimeError } from '../../../../hooks/use-runtime-error'
27
25
28
26
export function IssuesTab ( {
29
27
state,
@@ -34,39 +32,31 @@ export function IssuesTab({
34
32
runtimeErrors : ReadyRuntimeError [ ]
35
33
getSquashedHydrationErrorDetails : ( error : Error ) => HydrationErrorState | null
36
34
} ) {
37
- const [ activeIdx , setActiveIndex ] = useState < number > ( 0 )
38
- const activeError = useMemo < ReadyRuntimeError | null > (
39
- ( ) =>
40
- // TODO: correct fallback
41
- runtimeErrors [ activeIdx ] ?? {
42
- error : new Error ( 'No error' ) ,
43
- type : 'runtime' ,
44
- } ,
45
- [ activeIdx , runtimeErrors ]
46
- )
35
+ const {
36
+ isLoading,
37
+ errorCode,
38
+ errorType,
39
+ notes,
40
+ hydrationWarning,
41
+ activeIdx,
42
+ errorDetails,
43
+ activeError,
44
+ setActiveIndex,
45
+ } = useRuntimeError ( { runtimeErrors, getSquashedHydrationErrorDetails } )
46
+
47
+ if ( isLoading ) {
48
+ // TODO: better loading state
49
+ return null
50
+ }
47
51
48
52
if ( ! activeError ) {
49
53
return null
50
54
}
51
55
52
- // eslint-disable-next-line react-hooks/rules-of-hooks
53
- const errorDetails = useErrorDetails (
54
- activeError ?. error ,
55
- getSquashedHydrationErrorDetails
56
- )
57
-
58
- const error = activeError ?. error
59
-
60
- const errorCode = extractNextErrorCode ( error )
61
- const errorType = getErrorTypeLabel ( error , activeError . type )
62
- // TOOD: May be better to always treat everything past the first blank line as notes
63
- // We're currently only special casing hydration error messages.
64
- const notes = errorDetails . notes
65
- const hydrationWarning = errorDetails . hydrationWarning
66
56
const errorMessage = hydrationWarning ? (
67
57
< HydrationErrorDescription message = { hydrationWarning } />
68
58
) : (
69
- < GenericErrorDescription error = { error } />
59
+ < GenericErrorDescription error = { activeError . error } />
70
60
)
71
61
72
62
return (
@@ -96,11 +86,16 @@ export function IssuesTab({
96
86
>
97
87
< span data-nextjs-error-label-group >
98
88
< ErrorTypeLabel errorType = { errorType } />
99
- { error . environmentName && (
100
- < EnvironmentNameLabel environmentName = { error . environmentName } />
89
+ { activeError . error . environmentName && (
90
+ < EnvironmentNameLabel
91
+ environmentName = { activeError . error . environmentName }
92
+ />
101
93
) }
102
94
</ span >
103
- < ErrorOverlayToolbar error = { error } debugInfo = { state . debugInfo } />
95
+ < ErrorOverlayToolbar
96
+ error = { activeError . error }
97
+ debugInfo = { state . debugInfo }
98
+ />
104
99
</ div >
105
100
< ErrorMessage errorMessage = { errorMessage } />
106
101
</ div >
@@ -218,7 +213,7 @@ function Foo({
218
213
setActiveIndex,
219
214
} : {
220
215
runtimeError : ReadyRuntimeError
221
- errorType : string
216
+ errorType : string | null
222
217
idx : number
223
218
activeIdx : number
224
219
setActiveIndex : ( idx : number ) => void
0 commit comments