Fix rendering waterfall of suspended components in a single Suspense boundary #413
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I ran into an issue that is very similar to #335, where multiple suspended children in the same Suspense boundary throw a promise that bubbles out of the render functions, resulting in
Error: the promise {} was thrown, throw an Error :)
.This only occurs when there are 3+ direct children in a Suspense boundary, rendered async, where the Promises resolve one by one, which is why the test case added by #335 doesn't catch this.
Staggering the Promise resolves makes a key difference: with the existing test, rendering suspends on the Promise thrown in SuspenderOne, after which all three promises are resolved, and then rendering continues: SuspenderTwo and SuspenderThree never throw a promise.
preact-render-to-string/src/index.js
Lines 546 to 559 in 81e7da3
The issue arises here due to the use of
.then(onFulfilled, onRejected)
instead of.then(onFulfilled).catch(onRejected)
: when the onFulfilled callback throws an error here, it won't be caught.But after changing that in the code (which makes all the tests pass) I realised that block could also be simplified to just
Without the additional inline closure.