Skip to content

Commit f6e9235

Browse files
committed
fix(dev): strip windows working directory from rendered errors
1 parent 47b8387 commit f6e9235

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

packages/nuxt-cli/src/dev/error.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { SourceLoader, StackFrame } from 'youch-core/types'
44
import { readFile } from 'node:fs/promises'
55
import process from 'node:process'
66

7-
import { dirname, resolve } from 'pathe'
7+
import { dirname, normalize, resolve } from 'pathe'
88
import { SourceMapConsumer } from 'source-map'
99
import { Youch } from 'youch'
1010
import { ErrorParser } from 'youch-core'
@@ -59,7 +59,17 @@ export async function renderError(req: IncomingMessage, res: ServerResponse, err
5959
export async function renderErrorAnsi(error: unknown): Promise<string> {
6060
await loadStackTrace(error).catch(err => debug('Failed to load stack trace:', err))
6161
const ansi = await new Youch().toANSI(error)
62-
return ansi.replaceAll(process.cwd(), '.')
62+
return stripCwd(ansi)
63+
}
64+
65+
/**
66+
* Replace the working directory in rendered output with `.`.
67+
*
68+
* Frame filenames are normalised to forward slashes, so on Windows the native
69+
* `process.cwd()` spelling never matches and both forms have to be stripped.
70+
*/
71+
export function stripCwd(text: string, cwd = process.cwd()): string {
72+
return text.replaceAll(cwd, '.').replaceAll(normalize(cwd), '.')
6373
}
6474

6575
const sourceLoader: SourceLoader = async (frame) => {

packages/nuxt-cli/test/unit/errors.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { describe, expect, it } from 'vitest'
22

3+
import { stripCwd } from '../../src/dev/error'
34
import { isBrokenPipe } from '../../src/utils/errors'
45

56
describe('isBrokenPipe', () => {
@@ -14,3 +15,19 @@ describe('isBrokenPipe', () => {
1415
expect(isBrokenPipe(undefined)).toBe(false)
1516
})
1617
})
18+
19+
describe('stripCwd', () => {
20+
it('should strip posix working directories', () => {
21+
expect(stripCwd('at /home/me/app/pages/index.vue:3:1', '/home/me/app')).toBe('at ./pages/index.vue:3:1')
22+
})
23+
24+
it('should strip both spellings of a windows working directory', () => {
25+
const cwd = 'C:\\Users\\me\\app'
26+
expect(stripCwd('at C:/Users/me/app/pages/index.vue:3:1', cwd)).toBe('at ./pages/index.vue:3:1')
27+
expect(stripCwd('at C:\\Users\\me\\app\\pages\\index.vue:3:1', cwd)).toBe('at .\\pages\\index.vue:3:1')
28+
})
29+
30+
it('should leave unrelated paths alone', () => {
31+
expect(stripCwd('at /elsewhere/app/index.vue:1:1', '/home/me/app')).toBe('at /elsewhere/app/index.vue:1:1')
32+
})
33+
})

0 commit comments

Comments
 (0)