summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/happy-carrots-lick.md5
-rw-r--r--packages/astro/src/vite-plugin-astro-server/route.ts20
-rw-r--r--packages/astro/test/custom-404-html.test.js5
-rw-r--r--packages/astro/test/custom-404-injected.test.js5
-rw-r--r--packages/astro/test/custom-404-md.test.js5
-rw-r--r--packages/astro/test/custom-404-server.test.js5
-rw-r--r--packages/astro/test/custom-404.test.js5
-rw-r--r--packages/astro/test/units/dev/dev.test.js4
8 files changed, 45 insertions, 9 deletions
diff --git a/.changeset/happy-carrots-lick.md b/.changeset/happy-carrots-lick.md
new file mode 100644
index 000000000..7dcd38568
--- /dev/null
+++ b/.changeset/happy-carrots-lick.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fix `status` code for custom `404` and `500` pages in the dev server
diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts
index 8b8bf3482..d7b8c9a9e 100644
--- a/packages/astro/src/vite-plugin-astro-server/route.ts
+++ b/packages/astro/src/vite-plugin-astro-server/route.ts
@@ -25,7 +25,7 @@ type AsyncReturnType<T extends (...args: any) => Promise<any>> = T extends (
? R
: any;
-interface MatchedRoute {
+export interface MatchedRoute {
route: RouteData;
filePath: URL;
resolvedPathname: string;
@@ -125,12 +125,14 @@ type HandleRoute = {
incomingRequest: http.IncomingMessage;
incomingResponse: http.ServerResponse;
manifest: SSRManifest;
+ status?: number;
};
export async function handleRoute({
matchedRoute,
url,
pathname,
+ status = getStatus(matchedRoute),
body,
origin,
env,
@@ -198,6 +200,7 @@ export async function handleRoute({
matchedRoute: fourOhFourRoute,
url: new URL('/404', url),
pathname: '/404',
+ status: 404,
body,
origin,
env,
@@ -236,6 +239,7 @@ export async function handleRoute({
...options,
matchedRoute: fourOhFourRoute,
url: new URL(pathname, url),
+ status: 404,
body,
origin,
env,
@@ -246,6 +250,18 @@ export async function handleRoute({
});
}
throwIfRedirectNotAllowed(result, config);
- return await writeSSRResult(request, result, incomingResponse);
+
+ let response = result;
+ // Response.status is read-only, so a clone is required to override
+ if (status && response.status !== status) {
+ response = new Response(result.body, { ...result, status });
+ }
+ return await writeSSRResult(request, response, incomingResponse);
}
}
+
+function getStatus(matchedRoute?: MatchedRoute): number | undefined {
+ if (!matchedRoute) return 404;
+ if (matchedRoute.route.route === '/404') return 404;
+ if (matchedRoute.route.route === '/500') return 500;
+}
diff --git a/packages/astro/test/custom-404-html.test.js b/packages/astro/test/custom-404-html.test.js
index 6c3ac6dec..56d595165 100644
--- a/packages/astro/test/custom-404-html.test.js
+++ b/packages/astro/test/custom-404-html.test.js
@@ -32,7 +32,10 @@ describe('Custom 404.html', () => {
});
it('renders 404 for /a', async () => {
- const html = await fixture.fetch('/a').then((res) => res.text());
+ const res = await fixture.fetch('/a');
+ expect(res.status).to.equal(404);
+
+ const html = await res.text();
$ = cheerio.load(html);
expect($('h1').text()).to.equal('Page not found');
diff --git a/packages/astro/test/custom-404-injected.test.js b/packages/astro/test/custom-404-injected.test.js
index c8963243a..7940bde88 100644
--- a/packages/astro/test/custom-404-injected.test.js
+++ b/packages/astro/test/custom-404-injected.test.js
@@ -32,7 +32,10 @@ describe('Custom 404 with injectRoute', () => {
});
it('renders 404 for /a', async () => {
- const html = await fixture.fetch('/a').then((res) => res.text());
+ const res = await fixture.fetch('/a');
+ expect(res.status).to.equal(404);
+
+ const html = await res.text();
$ = cheerio.load(html);
expect($('h1').text()).to.equal('Page not found');
diff --git a/packages/astro/test/custom-404-md.test.js b/packages/astro/test/custom-404-md.test.js
index 69eddb26b..a7762004f 100644
--- a/packages/astro/test/custom-404-md.test.js
+++ b/packages/astro/test/custom-404-md.test.js
@@ -31,7 +31,10 @@ describe('Custom 404 Markdown', () => {
});
it('renders 404 for /abc', async () => {
- const html = await fixture.fetch('/a').then((res) => res.text());
+ const res = await fixture.fetch('/a');
+ expect(res.status).to.equal(404);
+
+ const html = await res.text();
$ = cheerio.load(html);
expect($('h1').text()).to.equal('Page not found');
diff --git a/packages/astro/test/custom-404-server.test.js b/packages/astro/test/custom-404-server.test.js
index db09bfbab..0c824546b 100644
--- a/packages/astro/test/custom-404-server.test.js
+++ b/packages/astro/test/custom-404-server.test.js
@@ -32,7 +32,10 @@ describe('Custom 404 server', () => {
});
it('renders 404 for /a', async () => {
- const html = await fixture.fetch('/a').then((res) => res.text());
+ const res = await fixture.fetch('/a');
+ expect(res.status).to.equal(404);
+
+ const html = await res.text();
$ = cheerio.load(html);
expect($('h1').text()).to.equal('Page not found');
diff --git a/packages/astro/test/custom-404.test.js b/packages/astro/test/custom-404.test.js
index a3294d9b1..c744f124c 100644
--- a/packages/astro/test/custom-404.test.js
+++ b/packages/astro/test/custom-404.test.js
@@ -32,7 +32,10 @@ describe('Custom 404', () => {
});
it('renders 404 for /a', async () => {
- const html = await fixture.fetch('/a').then((res) => res.text());
+ const res = await fixture.fetch('/a');
+ expect(res.status).to.equal(404);
+
+ const html = await res.text();
$ = cheerio.load(html);
expect($('h1').text()).to.equal('Page not found');
diff --git a/packages/astro/test/units/dev/dev.test.js b/packages/astro/test/units/dev/dev.test.js
index 5c19af635..7c361b9de 100644
--- a/packages/astro/test/units/dev/dev.test.js
+++ b/packages/astro/test/units/dev/dev.test.js
@@ -205,7 +205,7 @@ describe('dev container', () => {
await r.done;
const doc = await r.text();
expect(doc).to.match(/<h1>Custom 404<\/h1>/);
- expect(r.res.statusCode).to.equal(200);
+ expect(r.res.statusCode).to.equal(404);
}
{
// A non-existent page also serves the custom 404 page.
@@ -214,7 +214,7 @@ describe('dev container', () => {
await r.done;
const doc = await r.text();
expect(doc).to.match(/<h1>Custom 404<\/h1>/);
- expect(r.res.statusCode).to.equal(200);
+ expect(r.res.statusCode).to.equal(404);
}
}
);