Skip to content

Commit

Permalink
fix: 404 status in dev (#12980)
Browse files Browse the repository at this point in the history
  • Loading branch information
florian-lefebvre authored Jan 14, 2025
1 parent 1072c76 commit 1a026af
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/itchy-trains-allow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fixes a case where setting the status of a page to `404` in development would show the default 404 page (or custom one if provided) instead of using the current page
8 changes: 7 additions & 1 deletion packages/astro/src/vite-plugin-astro-server/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,13 @@ export async function handleRoute({
);
}

if (statusCode === 404 && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== 'no') {
if (
statusCode === 404 &&
// If the body isn't null, that means the user sets the 404 status
// but uses the current route to handle the 404
response.body === null &&
response.headers.get(REROUTE_DIRECTIVE_HEADER) !== 'no'
) {
const fourOhFourRoute = await matchRoute('/404', manifestData, pipeline);
if (fourOhFourRoute) {
renderContext = await RenderContext.create({
Expand Down
20 changes: 19 additions & 1 deletion packages/astro/test/astro-response.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// @ts-check
import assert from 'node:assert/strict';
import { after, before, describe, it } from 'node:test';
import { loadFixture } from './test-utils.js';

// Asset bundling
describe('Returning responses', () => {
/** @type {Awaited<ReturnType<typeof loadFixture>>} */
let fixture;
/** @type {import('./test-utils').DevServer} */
let devServer;
Expand All @@ -21,7 +23,23 @@ describe('Returning responses', () => {
});

it('Works from a page', async () => {
let response = await fixture.fetch('/not-found');
const response = await fixture.fetch('/not-found');
assert.equal(response.status, 404);
});

it('Returns the default 404 is body is null', async () => {
const response = await fixture.fetch('/not-found');
const html = await response.text();

assert.equal(response.status, 404);
assert.equal(html.includes('<pre>Path: /not-found</pre>'), true);
});

it('Returns the page is body is not null', async () => {
const response = await fixture.fetch('/not-found-custom');
const html = await response.text();

assert.equal(response.status, 404);
assert.equal(html.includes('Custom 404'), true);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
Astro.response.status = 404
---
<div>Custom 404</div>
4 changes: 2 additions & 2 deletions packages/astro/test/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ process.env.ASTRO_TELEMETRY_DISABLED = true;
* @property {typeof build} build
* @property {(url: string) => string} resolveUrl
* @property {(path: string) => Promise<boolean>} pathExists
* @property {(url: string, opts: Parameters<typeof fetch>[1]) => Promise<Response>} fetch
* @property {(url: string, opts?: Parameters<typeof fetch>[1]) => Promise<Response>} fetch
* @property {(path: string) => Promise<string>} readFile
* @property {(path: string, updater: (content: string) => string) => Promise<void>} editFile
* @property {(path: string) => Promise<string[]>} readdir
* @property {(pattern: string) => Promise<string[]>} glob
* @property {typeof dev} startDevServer
* @property {(inlineConfig?: Parameters<typeof dev>[0]) => ReturnType<typeof dev>} startDevServer
* @property {typeof preview} preview
* @property {() => Promise<void>} clean
* @property {() => Promise<App>} loadTestAdapterApp
Expand Down

0 comments on commit 1a026af

Please sign in to comment.