Fix errors that are not instanceof Error crashing the dev server (#5216)
* Fix errors that are not instanceof Error crashing the dev server * Update lockfile * Fix import paths
This commit is contained in:
parent
8c83359e38
commit
7fc5d55952
12 changed files with 74 additions and 11 deletions
|
@ -22,7 +22,7 @@ import { enableVerboseLogging, nodeLogDestination } from '../core/logger/node.js
|
||||||
import { formatConfigErrorMessage, formatErrorMessage, printHelp } from '../core/messages.js';
|
import { formatConfigErrorMessage, formatErrorMessage, printHelp } from '../core/messages.js';
|
||||||
import { appendForwardSlash } from '../core/path.js';
|
import { appendForwardSlash } from '../core/path.js';
|
||||||
import preview from '../core/preview/index.js';
|
import preview from '../core/preview/index.js';
|
||||||
import { createSafeError } from '../core/util.js';
|
import { createSafeError } from '../core/errors/index.js';
|
||||||
import * as event from '../events/index.js';
|
import * as event from '../events/index.js';
|
||||||
import { eventConfigError, eventError, telemetry } from '../events/index.js';
|
import { eventConfigError, eventError, telemetry } from '../events/index.js';
|
||||||
import { check } from './check/index.js';
|
import { check } from './check/index.js';
|
||||||
|
|
|
@ -9,4 +9,4 @@ export {
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
} from './errors.js';
|
} from './errors.js';
|
||||||
export { codeFrame } from './printer.js';
|
export { codeFrame } from './printer.js';
|
||||||
export { collectInfoFromStacktrace, positionAt } from './utils.js';
|
export { collectInfoFromStacktrace, positionAt, createSafeError } from './utils.js';
|
||||||
|
|
|
@ -118,3 +118,10 @@ function getLineOffsets(text: string) {
|
||||||
|
|
||||||
return lineOffsets;
|
return lineOffsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Coalesce any throw variable to an Error instance. */
|
||||||
|
export function createSafeError(err: any): Error {
|
||||||
|
return err instanceof Error || (err && err.name && err.message)
|
||||||
|
? err
|
||||||
|
: new Error(JSON.stringify(err));
|
||||||
|
}
|
||||||
|
|
|
@ -91,13 +91,6 @@ export function parseNpmName(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Coalesce any throw variable to an Error instance. */
|
|
||||||
export function createSafeError(err: any): Error {
|
|
||||||
return err instanceof Error || (err && err.name && err.message)
|
|
||||||
? err
|
|
||||||
: new Error(JSON.stringify(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function resolveDependency(dep: string, projectRoot: URL) {
|
export function resolveDependency(dep: string, projectRoot: URL) {
|
||||||
const resolved = resolve.sync(dep, {
|
const resolved = resolve.sync(dep, {
|
||||||
basedir: fileURLToPath(projectRoot),
|
basedir: fileURLToPath(projectRoot),
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { createRequest } from '../core/request.js';
|
||||||
import { createRouteManifest, matchAllRoutes } from '../core/routing/index.js';
|
import { createRouteManifest, matchAllRoutes } from '../core/routing/index.js';
|
||||||
import { resolvePages } from '../core/util.js';
|
import { resolvePages } from '../core/util.js';
|
||||||
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
|
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
|
||||||
|
import { createSafeError } from '../core/errors/index.js';
|
||||||
|
|
||||||
interface AstroPluginOptions {
|
interface AstroPluginOptions {
|
||||||
settings: AstroSettings;
|
settings: AstroSettings;
|
||||||
|
@ -284,7 +285,8 @@ async function handleRequest(
|
||||||
} catch (_err) {
|
} catch (_err) {
|
||||||
// This is our last line of defense regarding errors where we still might have some information about the request
|
// This is our last line of defense regarding errors where we still might have some information about the request
|
||||||
// Our error should already be complete, but let's try to add a bit more through some guesswork
|
// Our error should already be complete, but let's try to add a bit more through some guesswork
|
||||||
const errorWithMetadata = collectErrorMetadata(_err);
|
const err = createSafeError(_err);
|
||||||
|
const errorWithMetadata = collectErrorMetadata(err);
|
||||||
|
|
||||||
error(env.logging, null, msg.formatErrorMessage(errorWithMetadata));
|
error(env.logging, null, msg.formatErrorMessage(errorWithMetadata));
|
||||||
handle500Response(viteServer, origin, req, res, errorWithMetadata);
|
handle500Response(viteServer, origin, req, res, errorWithMetadata);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { readFileSync } from 'fs';
|
||||||
import type * as vite from 'vite';
|
import type * as vite from 'vite';
|
||||||
import { AstroErrorCodes } from '../core/errors/codes.js';
|
import { AstroErrorCodes } from '../core/errors/codes.js';
|
||||||
import { CSSError } from '../core/errors/errors.js';
|
import { CSSError } from '../core/errors/errors.js';
|
||||||
import { positionAt } from '../core/errors/utils.js';
|
import { positionAt } from '../core/errors/index.js';
|
||||||
|
|
||||||
export type ViteStyleTransformer = {
|
export type ViteStyleTransformer = {
|
||||||
viteDevServer?: vite.ViteDevServer;
|
viteDevServer?: vite.ViteDevServer;
|
||||||
|
|
33
packages/astro/test/error-non-error.test.js
Normal file
33
packages/astro/test/error-non-error.test.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import { expect } from 'chai';
|
||||||
|
import { loadFixture } from './test-utils.js';
|
||||||
|
|
||||||
|
describe('Can handle errors that are not instanceof Error', () => {
|
||||||
|
/** @type {import('./test-utils').Fixture} */
|
||||||
|
let fixture;
|
||||||
|
|
||||||
|
/** @type {import('./test-utils').DevServer} */
|
||||||
|
let devServer;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
fixture = await loadFixture({
|
||||||
|
root: './fixtures/error-non-error',
|
||||||
|
});
|
||||||
|
devServer = await fixture.startDevServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
after(async () => {
|
||||||
|
await devServer.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Does not crash the dev server', async () => {
|
||||||
|
let res = await fixture.fetch('/');
|
||||||
|
let html = await res.text();
|
||||||
|
|
||||||
|
expect(html).to.include('Error');
|
||||||
|
|
||||||
|
res = await fixture.fetch('/');
|
||||||
|
await res.text();
|
||||||
|
|
||||||
|
expect(html).to.include('Error');
|
||||||
|
});
|
||||||
|
});
|
3
packages/astro/test/fixtures/error-non-error/astro.config.mjs
vendored
Normal file
3
packages/astro/test/fixtures/error-non-error/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { defineConfig } from 'astro/config';
|
||||||
|
|
||||||
|
export default defineConfig({});
|
15
packages/astro/test/fixtures/error-non-error/package.json
vendored
Normal file
15
packages/astro/test/fixtures/error-non-error/package.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "@test/error-non-error",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "astro dev",
|
||||||
|
"start": "astro dev",
|
||||||
|
"build": "astro build",
|
||||||
|
"preview": "astro preview",
|
||||||
|
"astro": "astro"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"astro": "workspace:*"
|
||||||
|
}
|
||||||
|
}
|
1
packages/astro/test/fixtures/error-non-error/src/env.d.ts
vendored
Normal file
1
packages/astro/test/fixtures/error-non-error/src/env.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/// <reference types="astro/client" />
|
3
packages/astro/test/fixtures/error-non-error/src/pages/index.astro
vendored
Normal file
3
packages/astro/test/fixtures/error-non-error/src/pages/index.astro
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
throw {}
|
||||||
|
---
|
|
@ -1700,6 +1700,12 @@ importers:
|
||||||
dependencies:
|
dependencies:
|
||||||
astro: link:../../..
|
astro: link:../../..
|
||||||
|
|
||||||
|
packages/astro/test/fixtures/error-non-error:
|
||||||
|
specifiers:
|
||||||
|
astro: workspace:*
|
||||||
|
dependencies:
|
||||||
|
astro: link:../../..
|
||||||
|
|
||||||
packages/astro/test/fixtures/fetch:
|
packages/astro/test/fixtures/fetch:
|
||||||
specifiers:
|
specifiers:
|
||||||
'@astrojs/preact': workspace:*
|
'@astrojs/preact': workspace:*
|
||||||
|
|
Loading…
Reference in a new issue