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:
parent
d401866f93
commit
72bbfac976
8 changed files with 45 additions and 9 deletions
5
.changeset/happy-carrots-lick.md
Normal file
5
.changeset/happy-carrots-lick.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix `status` code for custom `404` and `500` pages in the dev server
|
|
@ -25,7 +25,7 @@ type AsyncReturnType<T extends (...args: any) => Promise<any>> = T extends (
|
||||||
? R
|
? R
|
||||||
: any;
|
: any;
|
||||||
|
|
||||||
interface MatchedRoute {
|
export interface MatchedRoute {
|
||||||
route: RouteData;
|
route: RouteData;
|
||||||
filePath: URL;
|
filePath: URL;
|
||||||
resolvedPathname: string;
|
resolvedPathname: string;
|
||||||
|
@ -125,12 +125,14 @@ type HandleRoute = {
|
||||||
incomingRequest: http.IncomingMessage;
|
incomingRequest: http.IncomingMessage;
|
||||||
incomingResponse: http.ServerResponse;
|
incomingResponse: http.ServerResponse;
|
||||||
manifest: SSRManifest;
|
manifest: SSRManifest;
|
||||||
|
status?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function handleRoute({
|
export async function handleRoute({
|
||||||
matchedRoute,
|
matchedRoute,
|
||||||
url,
|
url,
|
||||||
pathname,
|
pathname,
|
||||||
|
status = getStatus(matchedRoute),
|
||||||
body,
|
body,
|
||||||
origin,
|
origin,
|
||||||
env,
|
env,
|
||||||
|
@ -198,6 +200,7 @@ export async function handleRoute({
|
||||||
matchedRoute: fourOhFourRoute,
|
matchedRoute: fourOhFourRoute,
|
||||||
url: new URL('/404', url),
|
url: new URL('/404', url),
|
||||||
pathname: '/404',
|
pathname: '/404',
|
||||||
|
status: 404,
|
||||||
body,
|
body,
|
||||||
origin,
|
origin,
|
||||||
env,
|
env,
|
||||||
|
@ -236,6 +239,7 @@ export async function handleRoute({
|
||||||
...options,
|
...options,
|
||||||
matchedRoute: fourOhFourRoute,
|
matchedRoute: fourOhFourRoute,
|
||||||
url: new URL(pathname, url),
|
url: new URL(pathname, url),
|
||||||
|
status: 404,
|
||||||
body,
|
body,
|
||||||
origin,
|
origin,
|
||||||
env,
|
env,
|
||||||
|
@ -246,6 +250,18 @@ export async function handleRoute({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
throwIfRedirectNotAllowed(result, config);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -32,7 +32,10 @@ describe('Custom 404.html', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders 404 for /a', async () => {
|
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);
|
$ = cheerio.load(html);
|
||||||
|
|
||||||
expect($('h1').text()).to.equal('Page not found');
|
expect($('h1').text()).to.equal('Page not found');
|
||||||
|
|
|
@ -32,7 +32,10 @@ describe('Custom 404 with injectRoute', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders 404 for /a', async () => {
|
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);
|
$ = cheerio.load(html);
|
||||||
|
|
||||||
expect($('h1').text()).to.equal('Page not found');
|
expect($('h1').text()).to.equal('Page not found');
|
||||||
|
|
|
@ -31,7 +31,10 @@ describe('Custom 404 Markdown', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders 404 for /abc', async () => {
|
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);
|
$ = cheerio.load(html);
|
||||||
|
|
||||||
expect($('h1').text()).to.equal('Page not found');
|
expect($('h1').text()).to.equal('Page not found');
|
||||||
|
|
|
@ -32,7 +32,10 @@ describe('Custom 404 server', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders 404 for /a', async () => {
|
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);
|
$ = cheerio.load(html);
|
||||||
|
|
||||||
expect($('h1').text()).to.equal('Page not found');
|
expect($('h1').text()).to.equal('Page not found');
|
||||||
|
|
|
@ -32,7 +32,10 @@ describe('Custom 404', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders 404 for /a', async () => {
|
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);
|
$ = cheerio.load(html);
|
||||||
|
|
||||||
expect($('h1').text()).to.equal('Page not found');
|
expect($('h1').text()).to.equal('Page not found');
|
||||||
|
|
|
@ -205,7 +205,7 @@ describe('dev container', () => {
|
||||||
await r.done;
|
await r.done;
|
||||||
const doc = await r.text();
|
const doc = await r.text();
|
||||||
expect(doc).to.match(/<h1>Custom 404<\/h1>/);
|
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.
|
// A non-existent page also serves the custom 404 page.
|
||||||
|
@ -214,7 +214,7 @@ describe('dev container', () => {
|
||||||
await r.done;
|
await r.done;
|
||||||
const doc = await r.text();
|
const doc = await r.text();
|
||||||
expect(doc).to.match(/<h1>Custom 404<\/h1>/);
|
expect(doc).to.match(/<h1>Custom 404<\/h1>/);
|
||||||
expect(r.res.statusCode).to.equal(200);
|
expect(r.res.statusCode).to.equal(404);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Reference in a new issue