Skip to content

Commit b30d6e6

Browse files
committed
fix: error overlay on server hmr syntax error
1 parent 8bb8836 commit b30d6e6

2 files changed

Lines changed: 43 additions & 3 deletions

File tree

packages/plugin-rsc/src/plugin.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
} from './transforms'
3232
import { generateEncryptionKey, toBase64 } from './utils/encryption-utils'
3333
import { createRpcServer } from './utils/rpc'
34-
import { normalizeViteImportAnalysisUrl } from './vite-utils'
34+
import { normalizeViteImportAnalysisUrl, prepareError } from './vite-utils'
3535

3636
// state for build orchestration
3737
let serverReferences: Record<string, string> = {}
@@ -385,9 +385,22 @@ export default function vitePluginRsc(
385385
// transform js to surface syntax errors
386386
for (const mod of ctx.modules) {
387387
if (mod.type === 'js') {
388-
await this.environment.transformRequest(mod.url)
388+
try {
389+
await this.environment.transformRequest(mod.url)
390+
} catch (e) {
391+
server.environments.client.hot.send({
392+
type: 'error',
393+
err: prepareError(e as any),
394+
})
395+
throw e
396+
}
389397
}
390398
}
399+
// send empty client updates to clear error overlay if any
400+
ctx.server.environments.client.hot.send({
401+
type: 'update',
402+
updates: [],
403+
})
391404
// server hmr
392405
ctx.server.environments.client.hot.send({
393406
type: 'custom',

packages/plugin-rsc/src/vite-utils.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
import fs from 'node:fs'
44
import path from 'node:path'
5-
import type { DevEnvironment, Rollup } from 'vite'
5+
import type { DevEnvironment, ErrorPayload, Rollup } from 'vite'
6+
import { stripVTControlCharacters as strip } from 'node:util'
67

78
export const VALID_ID_PREFIX = `/@id/`
89

@@ -125,3 +126,29 @@ export function normalizeViteImportAnalysisUrl(
125126

126127
return url
127128
}
129+
130+
// error formatting
131+
// https://github.com/vitejs/vite/blob/8033e5bf8d3ff43995d0620490ed8739c59171dd/packages/vite/src/node/server/middlewares/error.ts#L11
132+
133+
type RollupError = Rollup.RollupError
134+
135+
export function prepareError(err: Error | RollupError): ErrorPayload['err'] {
136+
// only copy the information we need and avoid serializing unnecessary
137+
// properties, since some errors may attach full objects (e.g. PostCSS)
138+
return {
139+
message: strip(err.message),
140+
stack: strip(cleanStack(err.stack || '')),
141+
id: (err as RollupError).id,
142+
frame: strip((err as RollupError).frame || ''),
143+
plugin: (err as RollupError).plugin,
144+
pluginCode: (err as RollupError).pluginCode?.toString(),
145+
loc: (err as RollupError).loc,
146+
}
147+
}
148+
149+
function cleanStack(stack: string) {
150+
return stack
151+
.split(/\n/)
152+
.filter((l) => /^\s*at/.test(l))
153+
.join('\n')
154+
}

0 commit comments

Comments
 (0)