0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-03-31 23:31:30 -05:00

fix(app): call renderer when routes don't match (#13483)

* fix(app): call renderer when routes don't match

* chore: pick 404 exactly

* chore: pick route differently

Co-authored-by: ascorbic <213306+ascorbic@users.noreply.github.com>
This commit is contained in:
Emanuele Stoppa 2025-03-24 14:23:37 +00:00 committed by GitHub
parent 6b9020026f
commit fc2dcb8354
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 30 additions and 1 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fixes a bug where an Astro adapter couldn't call the middleware when there isn't a route that matches the incoming request.

View file

@ -7,6 +7,7 @@ import {
REROUTE_DIRECTIVE_HEADER,
clientAddressSymbol,
responseSentSymbol,
DEFAULT_404_COMPONENT,
} from '../constants.js';
import { getSetCookiesFromResponse } from '../cookies/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
@ -88,7 +89,6 @@ export class App {
#baseWithoutTrailingSlash: string;
#pipeline: AppPipeline;
#adapterLogger: AstroIntegrationLogger;
#renderOptionsDeprecationWarningShown = false;
constructor(manifest: SSRManifest, streaming = true) {
this.#manifest = manifest;
@ -331,6 +331,14 @@ export class App {
this.#logger.debug('router', 'Astro matched the following route for ' + request.url);
this.#logger.debug('router', 'RouteData:\n' + routeData);
}
// At this point we haven't found a route that matches the request, so we create
// a "fake" 404 route, so we can call the RenderContext.render
// and hit the middleware, which might be able to return a correct Response.
if (!routeData) {
routeData = this.#manifestData.routes.find(
(route) => route.component === '404.astro' || route.component === DEFAULT_404_COMPONENT,
);
}
if (!routeData) {
this.#logger.debug('router', "Astro hasn't found routes that match " + request.url);
this.#logger.debug('router', "Here's the available routes:\n", this.#manifestData);

View file

@ -8,6 +8,10 @@ export const onRequest = defineMiddleware((context, next) => {
},
});
}
if (context.url.pathname === '/does-not-exist') {
return context.rewrite('/rewrite');
}
return next();
});

View file

@ -318,6 +318,18 @@ describe('Middleware API in PROD mode, SSR', () => {
assert.equal(response.headers.get('content-type'), 'text/html');
});
it('can render a page that does not exist', async () => {
const request = new Request('http://example.com/does-not-exist');
const routeData = app.match(request);
const response = await app.render(request, { routeData });
assert.equal(response.status, 200);
const html = await response.text();
const $ = cheerio.load(html);
assert.equal($('p').html(), null);
assert.equal($('span').html(), 'New content!!');
});
it('can set locals for prerendered pages to use', async () => {
const text = await fixture.readFile('/client/prerendered/index.html');
assert.equal(text.includes('<p>yes they can!</p>'), true);