From 72bbfac976c2965a523eea88ff0543e64d848d80 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Tue, 18 Jul 2023 16:40:09 -0500 Subject: Fix 404 status code in dev server (#7711) * chore: update tests * chore: update tests * fix(#7516): set response status to 404 when rendering 404 page * chore: add changeset * chore: update dev container test * refactor: improve status handling logic * chore: remove unused import --- packages/astro/src/vite-plugin-astro-server/route.ts | 20 ++++++++++++++++++-- packages/astro/test/custom-404-html.test.js | 5 ++++- packages/astro/test/custom-404-injected.test.js | 5 ++++- packages/astro/test/custom-404-md.test.js | 5 ++++- packages/astro/test/custom-404-server.test.js | 5 ++++- packages/astro/test/custom-404.test.js | 5 ++++- packages/astro/test/units/dev/dev.test.js | 4 ++-- 7 files changed, 40 insertions(+), 9 deletions(-) (limited to 'packages') 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 Promise> = 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(/

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(/

Custom 404<\/h1>/); - expect(r.res.statusCode).to.equal(200); + expect(r.res.statusCode).to.equal(404); } } ); -- cgit v1.2.3