From 8d1b057ec1394cecdbc5a63b1c8b2cd443afa7b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Wed, 31 Aug 2022 18:40:17 -0400 Subject: [PATCH] [Flight] Minor error handling fixes (#25151) * Fix error handling when the Flight client itself errors * Serialize references to errors in the error priority queue It doesn't make sense to emit references to future values at higher pri than the value that they're referencing. This ensures that we don't emit hard forward references to values that don't yet exist. --- packages/react-client/src/ReactFlightClient.js | 5 +++++ .../src/ReactFlightDOMClient.js | 10 ++++++++-- packages/react-server/src/ReactFlightServer.js | 2 +- scripts/error-codes/codes.json | 3 ++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/react-client/src/ReactFlightClient.js b/packages/react-client/src/ReactFlightClient.js index 13fb0897e747b..d6ae368abf12c 100644 --- a/packages/react-client/src/ReactFlightClient.js +++ b/packages/react-client/src/ReactFlightClient.js @@ -312,6 +312,11 @@ export function parseModelString( } else { const id = parseInt(value.substring(1), 16); const chunk = getChunk(response, id); + if (chunk._status === PENDING) { + throw new Error( + "We didn't expect to see a forward reference. This is a bug in the React Server.", + ); + } return readChunk(chunk); } } diff --git a/packages/react-server-dom-webpack/src/ReactFlightDOMClient.js b/packages/react-server-dom-webpack/src/ReactFlightDOMClient.js index d8b5def41e041..32f8e794f4f70 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightDOMClient.js +++ b/packages/react-server-dom-webpack/src/ReactFlightDOMClient.js @@ -35,12 +35,18 @@ function startReadingFromStream( } const buffer: Uint8Array = (value: any); processBinaryChunk(response, buffer); - return reader.read().then(progress, error); + return reader + .read() + .then(progress) + .catch(error); } function error(e) { reportGlobalError(response, e); } - reader.read().then(progress, error); + reader + .read() + .then(progress) + .catch(error); } function createFromReadableStream( diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index 1577687c0040e..2a994fc8f32fd 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -902,7 +902,7 @@ function abortTask(task: Task, request: Request, errorId: number): void { // has a single value referencing the error. const ref = serializeByValueID(errorId); const processedChunk = processReferenceChunk(request, task.id, ref); - request.completedJSONChunks.push(processedChunk); + request.completedErrorChunks.push(processedChunk); } function flushCompletedChunks( diff --git a/scripts/error-codes/codes.json b/scripts/error-codes/codes.json index 423b30de52dd2..4817eadd99031 100644 --- a/scripts/error-codes/codes.json +++ b/scripts/error-codes/codes.json @@ -423,5 +423,6 @@ "435": "Unexpected Suspense handler tag (%s). This is a bug in React.", "436": "Stylesheet resources need a unique representation in the DOM while hydrating and more than one matching DOM Node was found. To fix, ensure you are only rendering one stylesheet link with an href attribute of \"%s\".", "437": "the \"precedence\" prop for links to stylesheets expects to receive a string but received something of type \"%s\" instead.", - "438": "An unsupported type was passed to use(): %s" + "438": "An unsupported type was passed to use(): %s", + "439": "We didn't expect to see a forward reference. This is a bug in the React Server." }