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:
Erika 2022-10-27 15:44:48 -03:00 committed by GitHub
parent 8c83359e38
commit 7fc5d55952
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 74 additions and 11 deletions

View file

@ -22,7 +22,7 @@ import { enableVerboseLogging, nodeLogDestination } from '../core/logger/node.js
import { formatConfigErrorMessage, formatErrorMessage, printHelp } from '../core/messages.js';
import { appendForwardSlash } from '../core/path.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 { eventConfigError, eventError, telemetry } from '../events/index.js';
import { check } from './check/index.js';

View file

@ -9,4 +9,4 @@ export {
RuntimeError,
} from './errors.js';
export { codeFrame } from './printer.js';
export { collectInfoFromStacktrace, positionAt } from './utils.js';
export { collectInfoFromStacktrace, positionAt, createSafeError } from './utils.js';

View file

@ -118,3 +118,10 @@ function getLineOffsets(text: string) {
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));
}

View file

@ -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) {
const resolved = resolve.sync(dep, {
basedir: fileURLToPath(projectRoot),

View file

@ -18,6 +18,7 @@ import { createRequest } from '../core/request.js';
import { createRouteManifest, matchAllRoutes } from '../core/routing/index.js';
import { resolvePages } from '../core/util.js';
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
import { createSafeError } from '../core/errors/index.js';
interface AstroPluginOptions {
settings: AstroSettings;
@ -284,7 +285,8 @@ async function handleRequest(
} catch (_err) {
// 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
const errorWithMetadata = collectErrorMetadata(_err);
const err = createSafeError(_err);
const errorWithMetadata = collectErrorMetadata(err);
error(env.logging, null, msg.formatErrorMessage(errorWithMetadata));
handle500Response(viteServer, origin, req, res, errorWithMetadata);

View file

@ -7,7 +7,7 @@ import { readFileSync } from 'fs';
import type * as vite from 'vite';
import { AstroErrorCodes } from '../core/errors/codes.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 = {
viteDevServer?: vite.ViteDevServer;

View 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');
});
});

View file

@ -0,0 +1,3 @@
import { defineConfig } from 'astro/config';
export default defineConfig({});

View 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:*"
}
}

View file

@ -0,0 +1 @@
/// <reference types="astro/client" />

View file

@ -0,0 +1,3 @@
---
throw {}
---

View file

@ -1700,6 +1700,12 @@ importers:
dependencies:
astro: link:../../..
packages/astro/test/fixtures/error-non-error:
specifiers:
astro: workspace:*
dependencies:
astro: link:../../..
packages/astro/test/fixtures/fetch:
specifiers:
'@astrojs/preact': workspace:*