mirror of
https://github.com/vitejs/vite.git
synced 2024-11-21 14:48:41 +00:00
fix(ssr): preserve fetchModule error details (#18626)
This commit is contained in:
parent
9eab231c7b
commit
866a433a34
@ -1,5 +1,6 @@
|
|||||||
packages/*/CHANGELOG.md
|
packages/*/CHANGELOG.md
|
||||||
packages/vite/src/node/ssr/runtime/__tests__/fixtures
|
packages/vite/src/node/ssr/runtime/__tests__/fixtures
|
||||||
|
packages/vite/src/node/ssr/__tests__/fixtures/errors
|
||||||
playground-temp/
|
playground-temp/
|
||||||
dist/
|
dist/
|
||||||
temp/
|
temp/
|
||||||
|
@ -213,6 +213,7 @@ export const normalizeHotChannel = (
|
|||||||
name: error.name,
|
name: error.name,
|
||||||
message: error.message,
|
message: error.message,
|
||||||
stack: error.stack,
|
stack: error.stack,
|
||||||
|
...error, // preserve enumerable properties such as RollupError.loc, frame, plugin
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
|
exports[`parse error 1`] = `
|
||||||
|
{
|
||||||
|
"frame": "
|
||||||
|
Expected ";" but found "code"
|
||||||
|
1 | invalid code
|
||||||
|
| ^
|
||||||
|
2 |
|
||||||
|
",
|
||||||
|
"id": "<root>/fixtures/errors/syntax-error.ts",
|
||||||
|
"loc": {
|
||||||
|
"column": 8,
|
||||||
|
"file": "<root>/fixtures/errors/syntax-error.ts",
|
||||||
|
"line": 1,
|
||||||
|
},
|
||||||
|
"message": "Transform failed with 1 error:
|
||||||
|
<root>/fixtures/errors/syntax-error.ts:1:8: ERROR: Expected ";" but found "code"",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`parse error 2`] = `
|
||||||
|
{
|
||||||
|
"frame": "",
|
||||||
|
"id": "",
|
||||||
|
"loc": undefined,
|
||||||
|
"message": "Expected ';', '}' or <eof>",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`parse error 3`] = `
|
||||||
|
{
|
||||||
|
"frame": "
|
||||||
|
Expected ";" but found "code"
|
||||||
|
1 | invalid code
|
||||||
|
| ^
|
||||||
|
2 |
|
||||||
|
",
|
||||||
|
"id": "<root>/fixtures/errors/syntax-error.ts",
|
||||||
|
"loc": {
|
||||||
|
"column": 8,
|
||||||
|
"file": "<root>/fixtures/errors/syntax-error.ts",
|
||||||
|
"line": 1,
|
||||||
|
},
|
||||||
|
"message": "Transform failed with 1 error:
|
||||||
|
<root>/fixtures/errors/syntax-error.ts:1:8: ERROR: Expected ";" but found "code"",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`parse error 4`] = `
|
||||||
|
{
|
||||||
|
"frame": "",
|
||||||
|
"id": "",
|
||||||
|
"loc": undefined,
|
||||||
|
"message": "Expected ';', '}' or <eof>",
|
||||||
|
}
|
||||||
|
`;
|
@ -0,0 +1 @@
|
|||||||
|
import './syntax-error.js'
|
@ -0,0 +1 @@
|
|||||||
|
import './syntax-error.ts'
|
@ -0,0 +1 @@
|
|||||||
|
invalid code
|
@ -0,0 +1 @@
|
|||||||
|
invalid code
|
@ -1,5 +1,6 @@
|
|||||||
import { fileURLToPath } from 'node:url'
|
import { fileURLToPath } from 'node:url'
|
||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
|
import { stripVTControlCharacters } from 'node:util'
|
||||||
import { expect, test } from 'vitest'
|
import { expect, test } from 'vitest'
|
||||||
import { createServer } from '../../server'
|
import { createServer } from '../../server'
|
||||||
import { normalizePath } from '../../utils'
|
import { normalizePath } from '../../utils'
|
||||||
@ -178,3 +179,36 @@ test('can access nodejs global', async () => {
|
|||||||
const mod = await server.ssrLoadModule('/fixtures/global/test.js')
|
const mod = await server.ssrLoadModule('/fixtures/global/test.js')
|
||||||
expect(mod.default).toBe(globalThis)
|
expect(mod.default).toBe(globalThis)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('parse error', async () => {
|
||||||
|
const server = await createDevServer()
|
||||||
|
|
||||||
|
function stripRoot(s?: string) {
|
||||||
|
return (s || '').replace(server.config.root, '<root>')
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of [
|
||||||
|
'/fixtures/errors/syntax-error.ts',
|
||||||
|
'/fixtures/errors/syntax-error.js',
|
||||||
|
'/fixtures/errors/syntax-error-dep.ts',
|
||||||
|
'/fixtures/errors/syntax-error-dep.js',
|
||||||
|
]) {
|
||||||
|
try {
|
||||||
|
await server.ssrLoadModule(file)
|
||||||
|
} catch (e) {
|
||||||
|
expect(e).toBeInstanceOf(Error)
|
||||||
|
expect({
|
||||||
|
message: stripRoot(e.message),
|
||||||
|
frame: stripVTControlCharacters(e.frame || ''),
|
||||||
|
id: stripRoot(e.id),
|
||||||
|
loc: e.loc && {
|
||||||
|
file: stripRoot(e.loc.file),
|
||||||
|
column: e.loc.column,
|
||||||
|
line: e.loc.line,
|
||||||
|
},
|
||||||
|
}).toMatchSnapshot()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
expect.unreachable()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
@ -32,6 +32,10 @@ type InvokeableModuleRunnerTransport = Omit<ModuleRunnerTransport, 'invoke'> & {
|
|||||||
): Promise<ReturnType<Awaited<InvokeMethods[T]>>>
|
): Promise<ReturnType<Awaited<InvokeMethods[T]>>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reviveInvokeError(e: any) {
|
||||||
|
return Object.assign(new Error(e.message || 'Unknown invoke error'), e)
|
||||||
|
}
|
||||||
|
|
||||||
const createInvokeableTransport = (
|
const createInvokeableTransport = (
|
||||||
transport: ModuleRunnerTransport,
|
transport: ModuleRunnerTransport,
|
||||||
): InvokeableModuleRunnerTransport => {
|
): InvokeableModuleRunnerTransport => {
|
||||||
@ -49,7 +53,7 @@ const createInvokeableTransport = (
|
|||||||
} satisfies InvokeSendData,
|
} satisfies InvokeSendData,
|
||||||
} satisfies CustomPayload)
|
} satisfies CustomPayload)
|
||||||
if ('e' in result) {
|
if ('e' in result) {
|
||||||
throw result.e
|
throw reviveInvokeError(result.e)
|
||||||
}
|
}
|
||||||
return result.r
|
return result.r
|
||||||
},
|
},
|
||||||
@ -90,7 +94,7 @@ const createInvokeableTransport = (
|
|||||||
|
|
||||||
const { e, r } = data.data
|
const { e, r } = data.data
|
||||||
if (e) {
|
if (e) {
|
||||||
promise.reject(e)
|
promise.reject(reviveInvokeError(e))
|
||||||
} else {
|
} else {
|
||||||
promise.resolve(r)
|
promise.resolve(r)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user