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
This commit is contained in:
Nate Moore 2023-07-18 16:40:09 -05:00 committed by GitHub
parent d401866f93
commit 72bbfac976
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 45 additions and 9 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fix `status` code for custom `404` and `500` pages in the dev server

View file

@ -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;
}

View file

@ -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');

View file

@ -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');

View file

@ -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');

View file

@ -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');

View file

@ -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');

View file

@ -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);
}
}
);