From 5f41cc54eb6f6d84737ccaa3ddae2bcc5709af8c Mon Sep 17 00:00:00 2001 From: fcFn Date: Wed, 29 Mar 2023 16:55:11 +0200 Subject: [PATCH] Fix incorrect path in error overlay on Win (#6679) --- .changeset/honest-paws-behave.md | 5 +++++ packages/astro/e2e/errors.test.js | 22 +++++++++++++++++++++ packages/astro/e2e/test-utils.js | 9 ++++++--- packages/astro/src/core/errors/dev/utils.ts | 9 ++++++++- packages/astro/src/core/errors/overlay.ts | 3 ++- 5 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 .changeset/honest-paws-behave.md diff --git a/.changeset/honest-paws-behave.md b/.changeset/honest-paws-behave.md new file mode 100644 index 000000000000..51351376fc7e --- /dev/null +++ b/.changeset/honest-paws-behave.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix incorrect path to file in error overlay on Win diff --git a/packages/astro/e2e/errors.test.js b/packages/astro/e2e/errors.test.js index ce867aa36ea5..8efcb40cfdb7 100644 --- a/packages/astro/e2e/errors.test.js +++ b/packages/astro/e2e/errors.test.js @@ -52,6 +52,28 @@ test.describe('Error display', () => { expect(await page.locator('vite-error-overlay').count()).toEqual(0); }); + test('shows correct file path when a page has an error', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/import-not-found')); + + const { fileLocation, absoluteFileLocation } = await getErrorOverlayContent(page); + const absoluteFileUrl = 'file://' + absoluteFileLocation.replace(/:\d+:\d+$/, ''); + const fileExists = astro.pathExists(absoluteFileUrl); + + expect(fileExists).toBeTruthy(); + expect(fileLocation).toMatch(/^pages\/import-not-found\.astro/); + }); + + test('shows correct file path when a component has an error', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/preact-runtime-error')); + + const { fileLocation, absoluteFileLocation } = await getErrorOverlayContent(page); + const absoluteFileUrl = 'file://' + absoluteFileLocation.replace(/:\d+:\d+$/, ''); + const fileExists = astro.pathExists(absoluteFileUrl); + + expect(fileExists).toBeTruthy(); + expect(fileLocation).toMatch(/^components\/PreactRuntimeError.jsx/); + }); + test('framework errors recover when fixed', async ({ page, astro }) => { await page.goto(astro.resolveUrl('/svelte-syntax-error')); diff --git a/packages/astro/e2e/test-utils.js b/packages/astro/e2e/test-utils.js index b75efeec41da..9fe6507dc1ef 100644 --- a/packages/astro/e2e/test-utils.js +++ b/packages/astro/e2e/test-utils.js @@ -35,7 +35,7 @@ export function testFactory(inlineConfig) { /** * * @param {string} page - * @returns {Promise<{message: string, hint: string}>} + * @returns {Promise<{message: string, hint: string, absoluteFileLocation: string, fileLocation: string}>} */ export async function getErrorOverlayContent(page) { const overlay = await page.waitForSelector('vite-error-overlay', { @@ -47,8 +47,11 @@ export async function getErrorOverlayContent(page) { const message = await overlay.$$eval('#message-content', (m) => m[0].textContent); const hint = await overlay.$$eval('#hint-content', (m) => m[0].textContent); - - return { message, hint }; + const [absoluteFileLocation, fileLocation] = await overlay.$$eval('#code header h2', (m) => [ + m[0].title, + m[0].textContent, + ]); + return { message, hint, absoluteFileLocation, fileLocation }; } /** diff --git a/packages/astro/src/core/errors/dev/utils.ts b/packages/astro/src/core/errors/dev/utils.ts index 4dd9aaaf7e52..15684746963b 100644 --- a/packages/astro/src/core/errors/dev/utils.ts +++ b/packages/astro/src/core/errors/dev/utils.ts @@ -4,11 +4,13 @@ import * as fs from 'node:fs'; import { isAbsolute, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import stripAnsi from 'strip-ansi'; +import { normalizePath } from 'vite'; import type { ESBuildTransformResult } from 'vite'; import type { SSRError } from '../../../@types/astro.js'; import { AggregateError, type ErrorWithMetadata } from '../errors.js'; import { codeFrame } from '../printer.js'; import { normalizeLF } from '../utils.js'; +import { removeLeadingForwardSlashWindows } from '../../path.js'; type EsbuildMessage = ESBuildTransformResult['warnings'][number]; @@ -32,10 +34,15 @@ export function collectErrorMetadata(e: any, rootFolder?: URL | undefined): Erro // - We'll fail to show the file's content in the browser // - We'll fail to show the code frame in the terminal // - The "Open in Editor" button won't work + + // Normalize the paths so that we can correctly detect if it's absolute on any platform + const normalizedFile = normalizePath(error.loc?.file || ''); + const normalizedRootFolder = removeLeadingForwardSlashWindows(rootFolder?.pathname || ''); + if ( error.loc?.file && rootFolder && - (!error.loc.file.startsWith(rootFolder.pathname) || !isAbsolute(error.loc.file)) + (!normalizedFile?.startsWith(normalizedRootFolder) || !isAbsolute(normalizedFile)) ) { error.loc.file = join(fileURLToPath(rootFolder), error.loc.file); } diff --git a/packages/astro/src/core/errors/overlay.ts b/packages/astro/src/core/errors/overlay.ts index c771547b1777..b7c9c8b94a28 100644 --- a/packages/astro/src/core/errors/overlay.ts +++ b/packages/astro/src/core/errors/overlay.ts @@ -637,7 +637,8 @@ class ErrorOverlay extends HTMLElement { const codeContent = code.querySelector('#code-content'); if (codeHeader) { - const cleanFile = err.loc.file.split('/').slice(-2).join('/'); + const separator = err.loc.file.includes('/') ? '/' : '\\'; + const cleanFile = err.loc.file.split(separator).slice(-2).join('/'); const fileLocation = [cleanFile, err.loc.line, err.loc.column].filter(Boolean).join(':'); const absoluteFileLocation = [err.loc.file, err.loc.line, err.loc.column] .filter(Boolean)