Fix incorrect path in error overlay on Win (#6679)

This commit is contained in:
Peter Timoshevsky 2023-03-31 13:07:19 +02:00 committed by GitHub
parent 46ecf46628
commit 08e92f4f8e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 43 additions and 5 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fix incorrect path to file in error overlay on Win

View file

@ -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'));

View file

@ -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 };
}
/**

View file

@ -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);
}

View file

@ -637,7 +637,8 @@ class ErrorOverlay extends HTMLElement {
const codeContent = code.querySelector<HTMLDivElement>('#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)