diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index ba2588b4a0ba..dbf929320af0 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -2765,7 +2765,7 @@ export type SSRComponentMetadata = { export interface SSRResult { /** * Whether the page has failed with a non-recoverable error, or the client disconnected. - */ + */ cancelled: boolean; styles: Set; scripts: Set; diff --git a/packages/astro/src/core/render-context.ts b/packages/astro/src/core/render-context.ts index 7460ad751673..36a27c6e8199 100644 --- a/packages/astro/src/core/render-context.ts +++ b/packages/astro/src/core/render-context.ts @@ -90,41 +90,41 @@ export class RenderContext { const lastNext = async () => { switch (routeData.type) { - case 'endpoint': return renderEndpoint(componentInstance as any, apiContext, serverLike, logger); - case 'redirect': return renderRedirect(this); + case 'endpoint': + return renderEndpoint(componentInstance as any, apiContext, serverLike, logger); + case 'redirect': + return renderRedirect(this); case 'page': { - const result = await this.createResult(componentInstance!); - let response: Response; - try { - response = await renderPage( - result, - componentInstance?.default as any, - props, - {}, - streaming, - routeData - ); - } catch (e) { - // If there is an error in the page's frontmatter or instantiation of the RenderTemplate fails midway, - // we signal to the rest of the internals that we can ignore the results of existing renders and avoid kicking off more of them. - result.cancelled = true; - throw e; - } - // Signal to the i18n middleware to maybe act on this response - response.headers.set(ROUTE_TYPE_HEADER, 'page'); - // Signal to the error-page-rerouting infra to let this response pass through to avoid loops - if (routeData.route === '/404' || routeData.route === '/500') { - response.headers.set(REROUTE_DIRECTIVE_HEADER, 'no'); - } - return response; + const result = await this.createResult(componentInstance!); + let response: Response; + try { + response = await renderPage( + result, + componentInstance?.default as any, + props, + {}, + streaming, + routeData + ); + } catch (e) { + // If there is an error in the page's frontmatter or instantiation of the RenderTemplate fails midway, + // we signal to the rest of the internals that we can ignore the results of existing renders and avoid kicking off more of them. + result.cancelled = true; + throw e; } - case 'fallback': { - return ( - new Response(null, { status: 500, headers: { [ROUTE_TYPE_HEADER]: 'fallback' } }) - ) + // Signal to the i18n middleware to maybe act on this response + response.headers.set(ROUTE_TYPE_HEADER, 'page'); + // Signal to the error-page-rerouting infra to let this response pass through to avoid loops + if (routeData.route === '/404' || routeData.route === '/500') { + response.headers.set(REROUTE_DIRECTIVE_HEADER, 'no'); } + return response; + } + case 'fallback': { + return new Response(null, { status: 500, headers: { [ROUTE_TYPE_HEADER]: 'fallback' } }); } } + }; const response = await callMiddleware(middleware, apiContext, lastNext); if (response.headers.get(ROUTE_TYPE_HEADER)) { diff --git a/packages/astro/src/runtime/server/render/astro/render.ts b/packages/astro/src/runtime/server/render/astro/render.ts index da771397edc0..37a78725a092 100644 --- a/packages/astro/src/runtime/server/render/astro/render.ts +++ b/packages/astro/src/runtime/server/render/astro/render.ts @@ -129,7 +129,7 @@ export async function renderToReadableStream( // If the client disconnects, // we signal to ignore the results of existing renders and avoid kicking off more of them. result.cancelled = true; - } + }, }); } diff --git a/packages/astro/src/runtime/server/render/component.ts b/packages/astro/src/runtime/server/render/component.ts index e4cc737acce0..280290b13164 100644 --- a/packages/astro/src/runtime/server/render/component.ts +++ b/packages/astro/src/runtime/server/render/component.ts @@ -459,13 +459,11 @@ export async function renderComponent( slots: any = {} ): Promise { if (isPromise(Component)) { - Component = await Component - .catch(handleCancellation); + Component = await Component.catch(handleCancellation); } if (isFragmentComponent(Component)) { - return await renderFragmentComponent(result, slots) - .catch(handleCancellation); + return await renderFragmentComponent(result, slots).catch(handleCancellation); } // Ensure directives (`class:list`) are processed @@ -473,16 +471,16 @@ export async function renderComponent( // .html components if (isHTMLComponent(Component)) { - return await renderHTMLComponent(result, Component, props, slots) - .catch(handleCancellation); + return await renderHTMLComponent(result, Component, props, slots).catch(handleCancellation); } if (isAstroComponentFactory(Component)) { return renderAstroComponent(result, displayName, Component, props, slots); } - return await renderFrameworkComponent(result, displayName, Component, props, slots) - .catch(handleCancellation); + return await renderFrameworkComponent(result, displayName, Component, props, slots).catch( + handleCancellation + ); function handleCancellation(e: unknown) { if (result.cancelled) return { render() {} }; diff --git a/packages/astro/test/streaming.test.js b/packages/astro/test/streaming.test.js index 6a0bdcf4e346..05e7dc53bcb2 100644 --- a/packages/astro/test/streaming.test.js +++ b/packages/astro/test/streaming.test.js @@ -78,7 +78,7 @@ describe('Streaming', () => { assert.equal(chunks.length > 1, true); }); - // if the offshoot promise goes unhandled, this test will pass immediately but fail the test suite + // if the offshoot promise goes unhandled, this test will pass immediately but fail the test suite it('Stays alive on failed component renders initiated by failed render templates', async () => { const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/multiple-errors');