Skip to content

Commit b731fe2

Browse files
Improve cyclic thenable detection in ReactFlightReplyServer (facebook#35369)
## Summary This PR improves cyclic thenable detection in `ReactFlightReplyServer.js`. Fixes facebook#35368. The previous fix only detected direct self-references (`inspectedValue === chunk`) and relied on the `cycleProtection` counter to eventually bail out of longer cycles. This change keeps the existing MAX_THENABLE_CYCLE_DEPTH ($1000$) `cycleProtection` cap as a hard guardrail and adds a visited set so that we can detect self-cycles and multi-node cycles as soon as any `ReactPromise` is revisited and while still bounding the amount of work we do for deep acyclic chains via `cycleProtection`. ## How did you test this change? - Ran the existing test suite for the server renderer: ```bash yarn test react-server yarn test --prod react-server yarn flow dom-node yarn linc ``` --------- Co-authored-by: Hendrik Liebau <mail@hendrik-liebau.de>
1 parent 88ee1f5 commit b731fe2

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

packages/react-server/src/ReactFlightReplyServer.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,20 @@ ReactPromise.prototype.then = function <T>(
133133
// Recursively check if the value is itself a ReactPromise and if so if it points
134134
// back to itself. This helps catch recursive thenables early error.
135135
let cycleProtection = 0;
136+
const visited = new Set<typeof ReactPromise>();
136137
while (inspectedValue instanceof ReactPromise) {
137138
cycleProtection++;
138-
if (inspectedValue === chunk || cycleProtection > 1000) {
139+
if (
140+
inspectedValue === chunk ||
141+
visited.has(inspectedValue) ||
142+
cycleProtection > 1000
143+
) {
139144
if (typeof reject === 'function') {
140145
reject(new Error('Cannot have cyclic thenables.'));
141146
}
142147
return;
143148
}
149+
visited.add(inspectedValue);
144150
if (inspectedValue.status === INITIALIZED) {
145151
inspectedValue = inspectedValue.value;
146152
} else {

0 commit comments

Comments
 (0)