diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js index 4c06d93bed6f9..049fa39d417a5 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js @@ -863,4 +863,46 @@ describe('ReactFlightDOMNode', () => { expect(ownerStack).toBeNull(); } }); + + // @gate experimental + // @gate enableHalt + it('can handle an empty prelude when prerendering', async () => { + function App() { + return null; + } + + const serverAbortController = new AbortController(); + serverAbortController.abort(); + const errors = []; + const {pendingResult} = await serverAct(async () => { + // destructure trick to avoid the act scope from awaiting the returned value + return { + pendingResult: ReactServerDOMStaticServer.unstable_prerender( + ReactServer.createElement(App, null), + webpackMap, + { + signal: serverAbortController.signal, + onError(error) { + errors.push(error); + }, + }, + ), + }; + }); + + expect(errors).toEqual([]); + + const {prelude} = await pendingResult; + + const reader = prelude.getReader(); + while (true) { + const {done} = await reader.read(); + if (done) { + break; + } + } + + // We don't really have an assertion other than to make sure + // the stream doesn't hang. + }); }); diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index 688a9ef0c574a..30698b8311acc 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -5762,6 +5762,7 @@ function flushCompletedChunks(request: Request): void { // TODO: If this destination is not currently flowing we'll not close it when it resumes flowing. // We should keep a separate status for this. if (request.destination !== null) { + request.status = CLOSED; close(request.destination); request.destination = null; } @@ -5779,8 +5780,8 @@ function flushCompletedChunks(request: Request): void { ); request.cacheController.abort(abortReason); } - request.status = CLOSED; if (request.destination !== null) { + request.status = CLOSED; close(request.destination); request.destination = null; }