Skip to content

Commit 050c0f9

Browse files
authored
fix(ssr): show ssr module loader error stack (#12651)
1 parent 15177a1 commit 050c0f9

File tree

1 file changed

+38
-34
lines changed

1 file changed

+38
-34
lines changed

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

+38-34
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type SSRModule = Record<string, any>
2828

2929
const pendingModules = new Map<string, Promise<SSRModule>>()
3030
const pendingImports = new Map<string, string[]>()
31+
const importErrors = new WeakMap<Error, { importee: string }>()
3132

3233
export async function ssrLoadModule(
3334
url: string,
@@ -131,32 +132,39 @@ async function instantiateModule(
131132
const pendingDeps: string[] = []
132133

133134
const ssrImport = async (dep: string) => {
134-
if (dep[0] !== '.' && dep[0] !== '/') {
135-
return nodeImport(dep, mod.file!, resolveOptions)
136-
}
137-
// convert to rollup URL because `pendingImports`, `moduleGraph.urlToModuleMap` requires that
138-
dep = unwrapId(dep)
139-
if (!isCircular(dep) && !pendingImports.get(dep)?.some(isCircular)) {
140-
pendingDeps.push(dep)
141-
if (pendingDeps.length === 1) {
142-
pendingImports.set(url, pendingDeps)
135+
try {
136+
if (dep[0] !== '.' && dep[0] !== '/') {
137+
return await nodeImport(dep, mod.file!, resolveOptions)
143138
}
144-
const mod = await ssrLoadModule(
145-
dep,
146-
server,
147-
context,
148-
urlStack,
149-
fixStacktrace,
150-
)
151-
if (pendingDeps.length === 1) {
152-
pendingImports.delete(url)
153-
} else {
154-
pendingDeps.splice(pendingDeps.indexOf(dep), 1)
139+
// convert to rollup URL because `pendingImports`, `moduleGraph.urlToModuleMap` requires that
140+
dep = unwrapId(dep)
141+
if (!isCircular(dep) && !pendingImports.get(dep)?.some(isCircular)) {
142+
pendingDeps.push(dep)
143+
if (pendingDeps.length === 1) {
144+
pendingImports.set(url, pendingDeps)
145+
}
146+
const mod = await ssrLoadModule(
147+
dep,
148+
server,
149+
context,
150+
urlStack,
151+
fixStacktrace,
152+
)
153+
if (pendingDeps.length === 1) {
154+
pendingImports.delete(url)
155+
} else {
156+
pendingDeps.splice(pendingDeps.indexOf(dep), 1)
157+
}
158+
// return local module to avoid race condition #5470
159+
return mod
155160
}
156-
// return local module to avoid race condition #5470
157-
return mod
161+
return moduleGraph.urlToModuleMap.get(dep)?.ssrModule
162+
} catch (err) {
163+
// tell external error handler which mod was imported with error
164+
importErrors.set(err, { importee: dep })
165+
166+
throw err
158167
}
159-
return moduleGraph.urlToModuleMap.get(dep)?.ssrModule
160168
}
161169

162170
const ssrDynamicImport = (dep: string) => {
@@ -204,6 +212,7 @@ async function instantiateModule(
204212
)
205213
} catch (e) {
206214
mod.ssrError = e
215+
const errorData = importErrors.get(e)
207216

208217
if (e.stack && fixStacktrace) {
209218
ssrFixStacktrace(e, moduleGraph)
@@ -212,7 +221,10 @@ async function instantiateModule(
212221
server.config.logger.error(
213222
colors.red(
214223
`Error when evaluating SSR module ${url}:` +
215-
(e.importee ? ` failed to import "${e.importee}"\n` : '\n'),
224+
(errorData?.importee
225+
? ` failed to import "${errorData.importee}"`
226+
: '') +
227+
`\n|- ${e.stack}\n`,
216228
),
217229
{
218230
timestamp: true,
@@ -221,7 +233,6 @@ async function instantiateModule(
221233
},
222234
)
223235

224-
delete e.importee
225236
throw e
226237
}
227238

@@ -262,15 +273,8 @@ async function nodeImport(
262273
}
263274
}
264275

265-
try {
266-
const mod = await dynamicImport(url)
267-
return proxyESM(mod)
268-
} catch (err) {
269-
// tell external error handler which mod was imported with error
270-
err.importee = id
271-
272-
throw err
273-
}
276+
const mod = await dynamicImport(url)
277+
return proxyESM(mod)
274278
}
275279

276280
// rollup-style default import interop for cjs

0 commit comments

Comments
 (0)