diff --git a/.changeset/blue-pugs-provide.md b/.changeset/blue-pugs-provide.md new file mode 100644 index 00000000000..dd222967ef4 --- /dev/null +++ b/.changeset/blue-pugs-provide.md @@ -0,0 +1,8 @@ +--- +'@whatwg-node/server': patch +--- + +While calling `handleNodeRequest` or `handleNodeRequestAndResponse`, `waitUntil` is not added automatically as in `requestListener` for Node.js integration. +This change adds `waitUntil` into the `serverContext` if not present. + +Fixes the issue with Fastify integration that uses the mentioned methods \ No newline at end of file diff --git a/packages/server/src/createServerAdapter.ts b/packages/server/src/createServerAdapter.ts index 9eca3c134c1..fef9f223600 100644 --- a/packages/server/src/createServerAdapter.ts +++ b/packages/server/src/createServerAdapter.ts @@ -133,17 +133,19 @@ function createServerAdapter< function waitUntil(promiseLike: PromiseLike) { // Ensure that the disposable stack is created - ensureDisposableStack(); - waitUntilPromises.add(promiseLike); - promiseLike.then( - () => { - waitUntilPromises.delete(promiseLike); - }, - err => { - console.error(`Unexpected error while waiting: ${err.message || err}`); - waitUntilPromises.delete(promiseLike); - }, - ); + if (isPromise(promiseLike)) { + ensureDisposableStack(); + waitUntilPromises.add(promiseLike); + promiseLike.then( + () => { + waitUntilPromises.delete(promiseLike); + }, + err => { + console.error(`Unexpected error while waiting: ${err.message || err}`); + waitUntilPromises.delete(promiseLike); + }, + ); + } } if (options?.plugins != null) { @@ -250,6 +252,10 @@ function createServerAdapter< // TODO: Remove this on the next major version function handleNodeRequest(nodeRequest: NodeRequest, ...ctx: Partial[]) { const serverContext = ctx.length > 1 ? completeAssign(...ctx) : ctx[0] || {}; + // Ensure `waitUntil` is available in the server context + if (!serverContext.waitUntil) { + serverContext.waitUntil = waitUntil; + } const request = normalizeNodeRequest(nodeRequest, fetchAPI); return handleRequest(request, serverContext); } diff --git a/packages/server/test/fastify.spec.ts b/packages/server/test/fastify.spec.ts index aa0b1ce1628..87fe3717fcb 100644 --- a/packages/server/test/fastify.spec.ts +++ b/packages/server/test/fastify.spec.ts @@ -212,6 +212,33 @@ describe('Fastify', () => { reqBody: 'TEST', }); }); + + it('handles waitUntil', async () => { + const backgroundJob$ = createDeferredPromise(); + let backgroundJobDone = false; + backgroundJob$.promise.finally(() => { + backgroundJobDone = true; + }); + serverAdapter = createServerAdapter((_request: Request, ctx) => { + ctx.waitUntil(backgroundJob$.promise); + return new Response('OK'); + }); + const res = await fastifyServer.inject({ + url: '/mypath', + }); + expect(res.body).toEqual('OK'); + const dispose$ = Promise.resolve(serverAdapter.dispose()); + let disposeDone = false; + dispose$.then(() => { + disposeDone = true; + }); + expect(backgroundJobDone).toBe(false); + expect(disposeDone).toBe(false); + backgroundJob$.resolve(); + await dispose$; + expect(backgroundJobDone).toBe(true); + expect(disposeDone).toBe(true); + }); }, ); });