summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/orange-cycles-serve.md5
-rw-r--r--packages/astro/src/core/errors.ts23
-rw-r--r--packages/astro/src/vite-plugin-astro-server/index.ts2
-rw-r--r--packages/astro/test/error-bad-js.test.js34
-rw-r--r--packages/astro/test/fixtures/error-bad-js/astro.config.mjs3
-rw-r--r--packages/astro/test/fixtures/error-bad-js/package.json15
-rw-r--r--packages/astro/test/fixtures/error-bad-js/src/env.d.ts1
-rw-r--r--packages/astro/test/fixtures/error-bad-js/src/pages/index.astro16
-rw-r--r--packages/astro/test/fixtures/error-bad-js/src/something.js1
-rw-r--r--pnpm-lock.yaml6
10 files changed, 96 insertions, 10 deletions
diff --git a/.changeset/orange-cycles-serve.md b/.changeset/orange-cycles-serve.md
new file mode 100644
index 000000000..123593116
--- /dev/null
+++ b/.changeset/orange-cycles-serve.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Makes the dev server more resilient to crashes
diff --git a/packages/astro/src/core/errors.ts b/packages/astro/src/core/errors.ts
index d96fbe885..9b2c7c174 100644
--- a/packages/astro/src/core/errors.ts
+++ b/packages/astro/src/core/errors.ts
@@ -48,7 +48,10 @@ export function cleanErrorStack(stack: string) {
export function fixViteErrorMessage(_err: unknown, server?: ViteDevServer, filePath?: URL) {
const err = createSafeError(_err);
// Vite will give you better stacktraces, using sourcemaps.
- server?.ssrFixStacktrace(err);
+ try {
+ server?.ssrFixStacktrace(err);
+ } catch {}
+
// Fix: Astro.glob() compiles to import.meta.glob() by the time Vite sees it,
// so we need to update this error message in case it originally came from Astro.glob().
if (err.message === 'import.meta.glob() can only accept string literals.') {
@@ -57,14 +60,16 @@ export function fixViteErrorMessage(_err: unknown, server?: ViteDevServer, fileP
if (filePath && /failed to load module for ssr:/.test(err.message)) {
const importName = err.message.split('for ssr:').at(1)?.trim();
if (importName) {
- const content = fs.readFileSync(fileURLToPath(filePath)).toString();
- const lns = content.split('\n');
- const line = lns.findIndex((ln) => ln.includes(importName));
- if (line == -1) return err;
- const column = lns[line]?.indexOf(importName);
- if (!(err as any).id) {
- (err as any).id = `${fileURLToPath(filePath)}:${line + 1}:${column + 1}`;
- }
+ try {
+ const content = fs.readFileSync(fileURLToPath(filePath)).toString();
+ const lns = content.split('\n');
+ const line = lns.findIndex((ln) => ln.includes(importName));
+ if (line == -1) return err;
+ const column = lns[line]?.indexOf(importName);
+ if (!(err as any).id) {
+ (err as any).id = `${fileURLToPath(filePath)}:${line + 1}:${column + 1}`;
+ }
+ } catch {}
}
}
return err;
diff --git a/packages/astro/src/vite-plugin-astro-server/index.ts b/packages/astro/src/vite-plugin-astro-server/index.ts
index 5a550ec18..05f2b893a 100644
--- a/packages/astro/src/vite-plugin-astro-server/index.ts
+++ b/packages/astro/src/vite-plugin-astro-server/index.ts
@@ -348,7 +348,7 @@ async function handleRequest(
return await writeSSRResult(result, res);
}
} catch (_err) {
- const err = fixViteErrorMessage(createSafeError(_err), viteServer, filePath);
+ const err = fixViteErrorMessage(_err, viteServer, filePath);
const errorWithMetadata = collectErrorMetadata(err);
error(logging, null, msg.formatErrorMessage(errorWithMetadata));
handle500Response(viteServer, origin, req, res, errorWithMetadata);
diff --git a/packages/astro/test/error-bad-js.test.js b/packages/astro/test/error-bad-js.test.js
new file mode 100644
index 000000000..0f4c12e6d
--- /dev/null
+++ b/packages/astro/test/error-bad-js.test.js
@@ -0,0 +1,34 @@
+import { expect } from 'chai';
+import * as cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
+
+describe('Errors in JavaScript', () => {
+ /** @type {import('./test-utils').Fixture} */
+ let fixture;
+
+ /** @type {import('./test-utils').DevServer} */
+ let devServer;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/error-bad-js',
+ });
+ 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('ReferenceError');
+
+ res = await fixture.fetch('/');
+ await res.text();
+
+ expect(html).to.include('ReferenceError');
+ });
+});
diff --git a/packages/astro/test/fixtures/error-bad-js/astro.config.mjs b/packages/astro/test/fixtures/error-bad-js/astro.config.mjs
new file mode 100644
index 000000000..86dbfb924
--- /dev/null
+++ b/packages/astro/test/fixtures/error-bad-js/astro.config.mjs
@@ -0,0 +1,3 @@
+import { defineConfig } from 'astro/config';
+
+export default defineConfig({});
diff --git a/packages/astro/test/fixtures/error-bad-js/package.json b/packages/astro/test/fixtures/error-bad-js/package.json
new file mode 100644
index 000000000..6b7af585e
--- /dev/null
+++ b/packages/astro/test/fixtures/error-bad-js/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "@test/error-bad-js",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "dev": "astro dev",
+ "start": "astro dev",
+ "build": "astro build",
+ "preview": "astro preview",
+ "astro": "astro"
+ },
+ "dependencies": {
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/error-bad-js/src/env.d.ts b/packages/astro/test/fixtures/error-bad-js/src/env.d.ts
new file mode 100644
index 000000000..f964fe0cf
--- /dev/null
+++ b/packages/astro/test/fixtures/error-bad-js/src/env.d.ts
@@ -0,0 +1 @@
+/// <reference types="astro/client" />
diff --git a/packages/astro/test/fixtures/error-bad-js/src/pages/index.astro b/packages/astro/test/fixtures/error-bad-js/src/pages/index.astro
new file mode 100644
index 000000000..1fbac6699
--- /dev/null
+++ b/packages/astro/test/fixtures/error-bad-js/src/pages/index.astro
@@ -0,0 +1,16 @@
+---
+import something from '../something.js';
+---
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+ <meta name="viewport" content="width=device-width" />
+ <meta name="generator" content={Astro.generator} />
+ <title>Astro</title>
+ </head>
+ <body>
+ <h1>Astro</h1>
+ </body>
+</html>
diff --git a/packages/astro/test/fixtures/error-bad-js/src/something.js b/packages/astro/test/fixtures/error-bad-js/src/something.js
new file mode 100644
index 000000000..13a1c6352
--- /dev/null
+++ b/packages/astro/test/fixtures/error-bad-js/src/something.js
@@ -0,0 +1 @@
+export var foo = bar;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index fcb3c2d20..854833fcd 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1492,6 +1492,12 @@ importers:
'@astrojs/preact': link:../../../../integrations/preact
astro: link:../../..
+ packages/astro/test/fixtures/error-bad-js:
+ specifiers:
+ astro: workspace:*
+ dependencies:
+ astro: link:../../..
+
packages/astro/test/fixtures/fetch:
specifiers:
'@astrojs/preact': workspace:*