Skip to content

Commit feb8ce0

Browse files
authored
fix(ssr): skip rewriting stack trace if it's already rewritten (fixes #11037) (#11070)
fixes #11037
1 parent 9602686 commit feb8ce0

File tree

6 files changed

+61
-12
lines changed

6 files changed

+61
-12
lines changed

packages/vite/src/node/server/index.ts

+2-8
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,7 @@ import {
3131
} from '../utils'
3232
import { ssrLoadModule } from '../ssr/ssrModuleLoader'
3333
import { cjsSsrResolveExternals } from '../ssr/ssrExternal'
34-
import {
35-
rebindErrorStacktrace,
36-
ssrRewriteStacktrace,
37-
} from '../ssr/ssrStacktrace'
34+
import { ssrFixStacktrace, ssrRewriteStacktrace } from '../ssr/ssrStacktrace'
3835
import { ssrTransform } from '../ssr/ssrTransform'
3936
import {
4037
getDepsOptimizer,
@@ -388,10 +385,7 @@ export async function createServer(
388385
)
389386
},
390387
ssrFixStacktrace(e) {
391-
if (e.stack) {
392-
const stacktrace = ssrRewriteStacktrace(e.stack, moduleGraph)
393-
rebindErrorStacktrace(e, stacktrace)
394-
}
388+
ssrFixStacktrace(e, moduleGraph)
395389
},
396390
ssrRewriteStacktrace(stack: string) {
397391
return ssrRewriteStacktrace(stack, moduleGraph)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
throw new Error()

packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts

+20
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,23 @@ test('ssrLoad', async () => {
2121
)
2222
}
2323
})
24+
25+
test('error has same instance', async () => {
26+
expect.assertions(3)
27+
const s = Symbol()
28+
29+
const server = await createDevServer()
30+
try {
31+
await server.ssrLoadModule('/fixtures/modules/has-error.js')
32+
} catch (e) {
33+
expect(e[s]).toBeUndefined()
34+
e[s] = true
35+
expect(e[s]).toBe(true)
36+
}
37+
38+
try {
39+
await server.ssrLoadModule('/fixtures/modules/has-error.js')
40+
} catch (e) {
41+
expect(e[s]).toBe(true)
42+
}
43+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { fileURLToPath } from 'node:url'
2+
import { test } from 'vitest'
3+
import { createServer } from '../../server'
4+
5+
const root = fileURLToPath(new URL('./', import.meta.url))
6+
7+
async function createDevServer() {
8+
const server = await createServer({ configFile: false, root })
9+
server.pluginContainer.buildStart({})
10+
return server
11+
}
12+
13+
test('call rewriteStacktrace twice', async () => {
14+
const server = await createDevServer()
15+
for (let i = 0; i < 2; i++) {
16+
try {
17+
await server.ssrLoadModule('/fixtures/modules/has-error.js')
18+
} catch (e) {
19+
server.ssrFixStacktrace(e)
20+
}
21+
}
22+
})

packages/vite/src/node/ssr/ssrModuleLoader.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
ssrImportMetaKey,
1818
ssrModuleExportsKey,
1919
} from './ssrTransform'
20-
import { rebindErrorStacktrace, ssrRewriteStacktrace } from './ssrStacktrace'
20+
import { ssrFixStacktrace } from './ssrStacktrace'
2121

2222
interface SSRContext {
2323
global: typeof globalThis
@@ -203,10 +203,9 @@ async function instantiateModule(
203203
} catch (e) {
204204
mod.ssrError = e
205205
if (e.stack && fixStacktrace) {
206-
const stacktrace = ssrRewriteStacktrace(e.stack, moduleGraph)
207-
rebindErrorStacktrace(e, stacktrace)
206+
ssrFixStacktrace(e, moduleGraph)
208207
server.config.logger.error(
209-
`Error when evaluating SSR module ${url}:\n${stacktrace}`,
208+
`Error when evaluating SSR module ${url}:\n${e.stack}`,
210209
{
211210
timestamp: true,
212211
clear: server.config.clearScreen,

packages/vite/src/node/ssr/ssrStacktrace.ts

+13
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,16 @@ export function rebindErrorStacktrace(e: Error, stacktrace: string): void {
7171
e.stack = stacktrace
7272
}
7373
}
74+
75+
const rewroteStacktraces = new WeakSet()
76+
77+
export function ssrFixStacktrace(e: Error, moduleGraph: ModuleGraph): void {
78+
if (!e.stack) return
79+
// stacktrace shouldn't be rewritten more than once
80+
if (rewroteStacktraces.has(e)) return
81+
82+
const stacktrace = ssrRewriteStacktrace(e.stack, moduleGraph)
83+
rebindErrorStacktrace(e, stacktrace)
84+
85+
rewroteStacktraces.add(e)
86+
}

0 commit comments

Comments
 (0)