diff --git a/.changeset/clear-vans-sniff.md b/.changeset/clear-vans-sniff.md new file mode 100644 index 000000000000..626a8c50a0b2 --- /dev/null +++ b/.changeset/clear-vans-sniff.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: avoid hanging when `error()` is used while streaming promises from a server `load` function diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 3793fbae39a5..c3905d035b84 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -227,7 +227,6 @@ export async function render_response({ paths.reset(); } - // eslint-disable-next-line const { head, html, css } = options.async ? await rendered : rendered; return { head, html, css }; @@ -654,7 +653,7 @@ export async function render_response({ async start(controller) { controller.enqueue(text_encoder.encode(transformed + '\n')); for await (const chunk of chunks) { - controller.enqueue(text_encoder.encode(chunk)); + if (chunk.length) controller.enqueue(text_encoder.encode(chunk)); } controller.close(); }, diff --git a/packages/kit/test/apps/basics/src/routes/streaming/discarded-promise/+layout.server.js b/packages/kit/test/apps/basics/src/routes/streaming/discarded-promise/+layout.server.js new file mode 100644 index 000000000000..29a851f7d815 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/streaming/discarded-promise/+layout.server.js @@ -0,0 +1,5 @@ +export function load() { + return { + promise: Promise.resolve(42) + }; +} diff --git a/packages/kit/test/apps/basics/src/routes/streaming/discarded-promise/+page.server.js b/packages/kit/test/apps/basics/src/routes/streaming/discarded-promise/+page.server.js new file mode 100644 index 000000000000..92d86bc06404 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/streaming/discarded-promise/+page.server.js @@ -0,0 +1,5 @@ +import { error } from '@sveltejs/kit'; + +export function load() { + error(404); +} diff --git a/packages/kit/test/apps/basics/src/routes/streaming/discarded-promise/+page.svelte b/packages/kit/test/apps/basics/src/routes/streaming/discarded-promise/+page.svelte new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js index 61a8c9256320..eea785051107 100644 --- a/packages/kit/test/apps/basics/test/server.test.js +++ b/packages/kit/test/apps/basics/test/server.test.js @@ -1408,3 +1408,18 @@ test.describe('asset preload', () => { }); } }); + +test.describe('Streaming', () => { + test("Discarded promises from server load functions don't hang SSR request", async ({ + request + }) => { + let error; + try { + await request.get('/streaming/discarded-promise'); + } catch (e) { + error = e; + } + + expect(error).toBeUndefined(); + }); +});