From ae758ebccebc5c9bb75e90f38d02503d617a4ca4 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 13 Feb 2025 01:05:29 +0100 Subject: [PATCH 1/4] [error overlay] fix infinite loop when frames are failed to fetch --- .../internal/helpers/stack-frame.ts | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts b/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts index 71d9fa5411d49..f5034422b751e 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts +++ b/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts @@ -77,21 +77,42 @@ export async function getOriginalStackFrames( isAppDirectory: isAppDir, } - const res = await fetch('/__nextjs_original-stack-frames', { - method: 'POST', - body: JSON.stringify(req), - }) + let res: Response | undefined = undefined + let errored = false + let reason: string | undefined = undefined + try { + res = await fetch('/__nextjs_original-stack-frames', { + method: 'POST', + body: JSON.stringify(req), + }) + } catch (e) { + errored = true + reason = e + '' + } // When fails to fetch the original stack frames, we reject here to be // caught at `_getOriginalStackFrame()` and return the stack frames so // that the error overlay can render. + if (!res) { + return Promise.all( + frames.map((frame) => + getOriginalStackFrame(frame, { + status: 'rejected', + reason: 'Failed to fetch the original stack frames: No response', + }) + ) + ) + } if (!res.ok || res.status === 204) { - const reason = await res.text() + errored = true // if it's 204 the reason is empty, but we still need to mark as errored + reason = await res.text() + } + if (errored) { return Promise.all( frames.map((frame) => getOriginalStackFrame(frame, { status: 'rejected', - reason: `Failed to fetch the original stack frames: ${reason}`, + reason: `Failed to fetch the original stack frames ${reason ? `: ${reason}` : ''}`, }) ) ) From 57118b723e8a850f90a0f899b5d59aad415ba983 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 13 Feb 2025 01:09:47 +0100 Subject: [PATCH 2/4] merge branch --- .../internal/helpers/stack-frame.ts | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts b/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts index f5034422b751e..6aa2b98f2b03a 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts +++ b/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts @@ -78,8 +78,8 @@ export async function getOriginalStackFrames( } let res: Response | undefined = undefined - let errored = false let reason: string | undefined = undefined + let errored = false try { res = await fetch('/__nextjs_original-stack-frames', { method: 'POST', @@ -93,17 +93,7 @@ export async function getOriginalStackFrames( // When fails to fetch the original stack frames, we reject here to be // caught at `_getOriginalStackFrame()` and return the stack frames so // that the error overlay can render. - if (!res) { - return Promise.all( - frames.map((frame) => - getOriginalStackFrame(frame, { - status: 'rejected', - reason: 'Failed to fetch the original stack frames: No response', - }) - ) - ) - } - if (!res.ok || res.status === 204) { + if (res && (!res.ok || res.status === 204)) { errored = true // if it's 204 the reason is empty, but we still need to mark as errored reason = await res.text() } From 06f07b920ac4e87dfc7ff4f693f11470ce9ed753 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 13 Feb 2025 01:18:08 +0100 Subject: [PATCH 3/4] fix build --- .../internal/helpers/stack-frame.ts | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts b/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts index 6aa2b98f2b03a..4501de02032bf 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts +++ b/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts @@ -79,38 +79,35 @@ export async function getOriginalStackFrames( let res: Response | undefined = undefined let reason: string | undefined = undefined - let errored = false try { res = await fetch('/__nextjs_original-stack-frames', { method: 'POST', body: JSON.stringify(req), }) } catch (e) { - errored = true reason = e + '' } // When fails to fetch the original stack frames, we reject here to be // caught at `_getOriginalStackFrame()` and return the stack frames so // that the error overlay can render. - if (res && (!res.ok || res.status === 204)) { - errored = true // if it's 204 the reason is empty, but we still need to mark as errored - reason = await res.text() - } - if (errored) { + if (res && res.ok) { + const data = await res.json() return Promise.all( - frames.map((frame) => - getOriginalStackFrame(frame, { - status: 'rejected', - reason: `Failed to fetch the original stack frames ${reason ? `: ${reason}` : ''}`, - }) - ) + frames.map((frame, index) => getOriginalStackFrame(frame, data[index])) ) + } else { + if (res) { + reason = await res.text() + } } - - const data = await res.json() return Promise.all( - frames.map((frame, index) => getOriginalStackFrame(frame, data[index])) + frames.map((frame) => + getOriginalStackFrame(frame, { + status: 'rejected', + reason: `Failed to fetch the original stack frames ${reason ? `: ${reason}` : ''}`, + }) + ) ) } From a85be4c012ddf8b679525ff706183a3e83deaf65 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 13 Feb 2025 01:19:19 +0100 Subject: [PATCH 4/4] handle 204 --- .../react-dev-overlay/internal/helpers/stack-frame.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts b/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts index 4501de02032bf..6d1f86d22734c 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts +++ b/packages/next/src/client/components/react-dev-overlay/internal/helpers/stack-frame.ts @@ -91,7 +91,7 @@ export async function getOriginalStackFrames( // When fails to fetch the original stack frames, we reject here to be // caught at `_getOriginalStackFrame()` and return the stack frames so // that the error overlay can render. - if (res && res.ok) { + if (res && res.ok && res.status !== 204) { const data = await res.json() return Promise.all( frames.map((frame, index) => getOriginalStackFrame(frame, data[index]))