From a8e011417428b24daf6153e95c87791d487f2c74 Mon Sep 17 00:00:00 2001 From: Janka Uryga Date: Thu, 23 May 2024 01:17:24 +0200 Subject: [PATCH] [unstable_after] fix occasional dev-mode crash in edge runtime pages (#66099) When hot-reloading an edge runtime page, sometimes we randomly get this: ``` [InvariantError: Invariant: Cannot call onClose on a response that is already sent. This is a bug in Next.js.] { name: 'InvariantError' } ``` and since `unstable_after` relies on `onClose`, no callbacks are called. I believe this is because `web-server` [calls `res.send()` pretty early for streaming responses](https://github.com/vercel/next.js/blob/b9817f83519fdaa7a7fcd4711dfb80aa1e1a2434/packages/next/src/server/web-server.ts#L311), so `res.sent` becomes `true` even though we're still streaming, and prevents us from calling `onClose` in the streaming render. It makes more sense to check the CloseController's `isClosed` instead -- when that becomes `true`, we _really_ shouldn't call onClose anymore (points to a bug), but before that it's fine. --- packages/next/src/server/base-http/web.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/next/src/server/base-http/web.ts b/packages/next/src/server/base-http/web.ts index 1d0c17cabbfaf..ef8e3f3680663 100644 --- a/packages/next/src/server/base-http/web.ts +++ b/packages/next/src/server/base-http/web.ts @@ -137,9 +137,9 @@ export class WebNextResponse extends BaseNextResponse { 'Cannot call onClose on a WebNextResponse initialized with `trackOnClose = false`' ) } - if (this.sent) { + if (this.closeController.isClosed) { throw new InvariantError( - 'Cannot call onClose on a response that is already sent' + 'Cannot call onClose on a WebNextResponse that is already closed' ) } return this.closeController.onClose(callback)