From 81a919969525c4220506f4cdd2a5f371fb0bed41 Mon Sep 17 00:00:00 2001 From: "factory[bot]" Date: Tue, 6 Oct 2026 20:25:47 +0000 Subject: [PATCH] fix(astro): provide Astro.cache when rendering error pages --- .changeset/error-page-astro-cache.md | 5 +++++ packages/astro/src/core/errors/default-handler.ts | 2 ++ packages/astro/src/core/errors/dev-handler.ts | 2 ++ packages/astro/test/units/cache/app-cache.test.ts | 15 +++++++++++++++ 4 files changed, 24 insertions(+) create mode 100644 .changeset/error-page-astro-cache.md diff --git a/.changeset/error-page-astro-cache.md b/.changeset/error-page-astro-cache.md new file mode 100644 index 000000000000..12b8b908aa10 --- /dev/null +++ b/.changeset/error-page-astro-cache.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes `Astro.cache` being `undefined` when a custom 404 or 500 page is rendered by the error handler, for example after a request to an API route with an HTTP method the route doesn't export diff --git a/packages/astro/src/core/errors/default-handler.ts b/packages/astro/src/core/errors/default-handler.ts index f33eba1e5e7d..aebd8fe47222 100644 --- a/packages/astro/src/core/errors/default-handler.ts +++ b/packages/astro/src/core/errors/default-handler.ts @@ -10,6 +10,7 @@ import { handleMiddleware } from '../middleware/astro-middleware.js'; import { handlePages } from '../pages/handler.js'; import { matchRoute } from '../routing/match.js'; import { getRouteTable } from '../routing/route-table.js'; +import { provideCache } from '../cache/handler.js'; import { provideSession } from '../session/provider.js'; import { validateHost } from '../app/validate-headers.js'; import { getErrorRoutePath } from '../../i18n/error-routes.js'; @@ -113,6 +114,7 @@ export async function renderDefaultError( errorState.initialProps = { error }; try { await provideSession(errorState); + await provideCache(errorState); const response = await handleMiddleware(errorState, handlePages); // A middleware rewrite (`ctx.rewrite()` / `next(payload)`) issued while // rendering the error page swaps the state's routeData away from the diff --git a/packages/astro/src/core/errors/dev-handler.ts b/packages/astro/src/core/errors/dev-handler.ts index 79aa25658ee6..4a8394c39a5b 100644 --- a/packages/astro/src/core/errors/dev-handler.ts +++ b/packages/astro/src/core/errors/dev-handler.ts @@ -1,5 +1,6 @@ import type { RenderErrorOptions } from '../app/base.js'; import type { SSRManifest } from '../app/types.js'; +import { provideCache } from '../cache/handler.js'; import { getEnvironment } from '../environment/index.js'; import { FetchState } from '../fetch/fetch-state.js'; import type { RouteData } from '../../types/public/index.js'; @@ -66,6 +67,7 @@ export async function renderDevError( errorState.componentInstance = preloadedComponent; errorState.locals = resolvedRenderOptions.locals ?? ({} as App.Locals); errorState.initialProps = { error }; + await provideCache(errorState); const response = await handleMiddleware(errorState, handlePages); // A middleware rewrite issued while rendering the error page swaps the diff --git a/packages/astro/test/units/cache/app-cache.test.ts b/packages/astro/test/units/cache/app-cache.test.ts index cb33c62e01fd..a3839d9cb36b 100644 --- a/packages/astro/test/units/cache/app-cache.test.ts +++ b/packages/astro/test/units/cache/app-cache.test.ts @@ -620,6 +620,21 @@ describe('context.cache disabled (no provider configured)', () => { const body = await response.json(); assert.deepEqual(body, { ok: true }); }); + + it('Astro.cache is defined on the 404 page rendered for an unhandled API route method', async () => { + const notFoundPage = createComponent((result, props, slots) => { + const Astro = result.createAstro(props, slots); + Astro.cache.set({ maxAge: 120 }); + return render`${renderHead()}

Not Found

`; + }); + const app = createTestApp([ + createEndpoint({ POST: () => new Response('ok') }, { route: '/api/thing' }), + createPage(notFoundPage, { route: '/404' }), + ]); + const response = await app.render(new Request('http://example.com/api/thing')); + assert.equal(response.status, 404); + assert.match(await response.text(), /

Not Found<\/h1>/); + }); }); // #endregion