From 49c9ad826ea22044cd53f1075d46d522a426d3a6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 18:23:28 +0000 Subject: [PATCH 1/6] Initial plan From 86610ce5792031a93e462894f5e46b7a20ac8038 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 18:27:05 +0000 Subject: [PATCH 2/6] [AI] Update getBetterError tests for mutation behavior Co-authored-by: brillout <1005638+brillout@users.noreply.github.com> --- packages/vike/utils/getBetterError.spec.ts | 26 +++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/vike/utils/getBetterError.spec.ts b/packages/vike/utils/getBetterError.spec.ts index 6cb2f751aa2..f5dbbacfc09 100644 --- a/packages/vike/utils/getBetterError.spec.ts +++ b/packages/vike/utils/getBetterError.spec.ts @@ -272,11 +272,15 @@ describe('getBetterError', () => { }) describe('getOriginalError', () => { - it('returns the original error when no chain exists', () => { + it('returns a clone of the original error when no chain exists', () => { const error = new Error('Test') const result = getBetterError(error, {}) - expect(result.getOriginalError()).toBe(error) + const originalError = result.getOriginalError() + // getOriginalError returns a clone, not the same reference + expect(originalError).not.toBe(error) + // But it has the same message + expect(originalError.message).toBe(error.message) }) it('preserves getOriginalError chain', () => { @@ -284,8 +288,9 @@ describe('getBetterError', () => { const secondError = getBetterError(firstError, { message: 'Second error' }) const thirdError = getBetterError(secondError, { message: 'Third error' }) - expect(thirdError.getOriginalError()).toBe(firstError) - expect(secondError.getOriginalError()).toBe(firstError) + // Both should return clones with the original message + expect(thirdError.getOriginalError().message).toBe('First error') + expect(secondError.getOriginalError().message).toBe('First error') }) it('chains through multiple transformations', () => { @@ -294,23 +299,24 @@ describe('getBetterError', () => { const withAppend = getBetterError(withPrepend, { message: { append: ' [2]' } }) const withReplace = getBetterError(withAppend, { message: 'Replaced' }) - expect(withReplace.getOriginalError()).toBe(original) + expect(withReplace.getOriginalError().message).toBe('Original') }) }) - describe('structuredClone behavior', () => { - it('only preserves message and stack from Error objects', () => { + describe('error mutation behavior', () => { + it('preserves custom properties on Error objects', () => { const customError = new Error('Custom error') customError.code = 'E_CUSTOM' customError.statusCode = 500 const result = getBetterError(customError, {}) - // structuredClone only preserves message and stack from Error objects + // Custom properties are preserved because we mutate the error instead of cloning + // (to avoid breaking Vite's ssrFixStacktrace() internal rewroteStacktraces.has(err) check) expect(result.message).toBe('Custom error') expect(result.stack).toBeDefined() - expect(result.code).toBeUndefined() - expect(result.statusCode).toBeUndefined() + expect(result.code).toBe('E_CUSTOM') + expect(result.statusCode).toBe(500) }) }) From bd8d40950b7b269b7dc3038ea0c7bedec5c96f51 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 18:42:19 +0000 Subject: [PATCH 3/6] [AI] Fix getOriginalError chaining issue Co-authored-by: brillout <1005638+brillout@users.noreply.github.com> --- packages/vike/utils/getBetterError.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/vike/utils/getBetterError.ts b/packages/vike/utils/getBetterError.ts index 1564a3b5ce3..5293de8dddd 100644 --- a/packages/vike/utils/getBetterError.ts +++ b/packages/vike/utils/getBetterError.ts @@ -15,6 +15,8 @@ function getBetterError( err: unknown, modifications: { message?: string | { prepend?: string; append?: string }; stack?: string; hideStack?: true }, ) { + // Preserve getOriginalError before cloning (structuredClone doesn't preserve methods) + const getOriginalErrorFromErr = isObject(err) ? (err as any).getOriginalError : undefined const errOriginal = structuredClone(err) let errBetter: { message: string; stack: string; hideStack?: true } @@ -69,7 +71,7 @@ function getBetterError( } // Enable users to retrieve the original error - objectAssign(errBetter, { getOriginalError: () => (errOriginal as any)?.getOriginalError?.() ?? errOriginal }) + objectAssign(errBetter, { getOriginalError: () => getOriginalErrorFromErr?.() ?? errOriginal }) return errBetter } From ea88c1e6b8ae6bd8565e4c7913b2d0dbf0c8bd08 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 18:43:32 +0000 Subject: [PATCH 4/6] [AI] Improve type safety in getBetterError Co-authored-by: brillout <1005638+brillout@users.noreply.github.com> --- packages/vike/utils/getBetterError.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vike/utils/getBetterError.ts b/packages/vike/utils/getBetterError.ts index 5293de8dddd..7cefef1424a 100644 --- a/packages/vike/utils/getBetterError.ts +++ b/packages/vike/utils/getBetterError.ts @@ -16,7 +16,7 @@ function getBetterError( modifications: { message?: string | { prepend?: string; append?: string }; stack?: string; hideStack?: true }, ) { // Preserve getOriginalError before cloning (structuredClone doesn't preserve methods) - const getOriginalErrorFromErr = isObject(err) ? (err as any).getOriginalError : undefined + const getOriginalErrorFromErr = isObject(err) ? (err as { getOriginalError?: () => unknown }).getOriginalError : undefined const errOriginal = structuredClone(err) let errBetter: { message: string; stack: string; hideStack?: true } From 5df582121edd2e8f5b46706b87a2bf5a34ef0b0d Mon Sep 17 00:00:00 2001 From: Romuald Brillout Date: Sun, 14 Dec 2025 20:19:23 +0100 Subject: [PATCH 5/6] Revert "[AI] Improve type safety in getBetterError" This reverts commit ea88c1e6b8ae6bd8565e4c7913b2d0dbf0c8bd08. --- packages/vike/utils/getBetterError.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vike/utils/getBetterError.ts b/packages/vike/utils/getBetterError.ts index 7cefef1424a..5293de8dddd 100644 --- a/packages/vike/utils/getBetterError.ts +++ b/packages/vike/utils/getBetterError.ts @@ -16,7 +16,7 @@ function getBetterError( modifications: { message?: string | { prepend?: string; append?: string }; stack?: string; hideStack?: true }, ) { // Preserve getOriginalError before cloning (structuredClone doesn't preserve methods) - const getOriginalErrorFromErr = isObject(err) ? (err as { getOriginalError?: () => unknown }).getOriginalError : undefined + const getOriginalErrorFromErr = isObject(err) ? (err as any).getOriginalError : undefined const errOriginal = structuredClone(err) let errBetter: { message: string; stack: string; hideStack?: true } From 312eee211f7d984d56a90e7436d8d46dcf9e6088 Mon Sep 17 00:00:00 2001 From: Romuald Brillout Date: Sun, 14 Dec 2025 20:19:26 +0100 Subject: [PATCH 6/6] Revert "[AI] Fix getOriginalError chaining issue" This reverts commit bd8d40950b7b269b7dc3038ea0c7bedec5c96f51. --- packages/vike/utils/getBetterError.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/vike/utils/getBetterError.ts b/packages/vike/utils/getBetterError.ts index 5293de8dddd..1564a3b5ce3 100644 --- a/packages/vike/utils/getBetterError.ts +++ b/packages/vike/utils/getBetterError.ts @@ -15,8 +15,6 @@ function getBetterError( err: unknown, modifications: { message?: string | { prepend?: string; append?: string }; stack?: string; hideStack?: true }, ) { - // Preserve getOriginalError before cloning (structuredClone doesn't preserve methods) - const getOriginalErrorFromErr = isObject(err) ? (err as any).getOriginalError : undefined const errOriginal = structuredClone(err) let errBetter: { message: string; stack: string; hideStack?: true } @@ -71,7 +69,7 @@ function getBetterError( } // Enable users to retrieve the original error - objectAssign(errBetter, { getOriginalError: () => getOriginalErrorFromErr?.() ?? errOriginal }) + objectAssign(errBetter, { getOriginalError: () => (errOriginal as any)?.getOriginalError?.() ?? errOriginal }) return errBetter }