(root, returnFiber, sourceFiber, value, rootRenderLanes)
| 19008 | } |
| 19009 | |
| 19010 | function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) { |
| 19011 | // The source fiber did not complete. |
| 19012 | sourceFiber.flags |= Incomplete; |
| 19013 | |
| 19014 | { |
| 19015 | if (isDevToolsPresent) { |
| 19016 | // If we have pending work still, restore the original updaters |
| 19017 | restorePendingUpdaters(root, rootRenderLanes); |
| 19018 | } |
| 19019 | } |
| 19020 | |
| 19021 | if (value !== null && typeof value === 'object' && typeof value.then === 'function') { |
| 19022 | // This is a wakeable. The component suspended. |
| 19023 | var wakeable = value; |
| 19024 | resetSuspendedComponent(sourceFiber); |
| 19025 | |
| 19026 | { |
| 19027 | if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) { |
| 19028 | markDidThrowWhileHydratingDEV(); |
| 19029 | } |
| 19030 | } |
| 19031 | |
| 19032 | |
| 19033 | var suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber); |
| 19034 | |
| 19035 | if (suspenseBoundary !== null) { |
| 19036 | suspenseBoundary.flags &= ~ForceClientRender; |
| 19037 | markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // We only attach ping listeners in concurrent mode. Legacy Suspense always |
| 19038 | // commits fallbacks synchronously, so there are no pings. |
| 19039 | |
| 19040 | if (suspenseBoundary.mode & ConcurrentMode) { |
| 19041 | attachPingListener(root, wakeable, rootRenderLanes); |
| 19042 | } |
| 19043 | |
| 19044 | attachRetryListener(suspenseBoundary, root, wakeable); |
| 19045 | return; |
| 19046 | } else { |
| 19047 | // No boundary was found. Unless this is a sync update, this is OK. |
| 19048 | // We can suspend and wait for more data to arrive. |
| 19049 | if (!includesSyncLane(rootRenderLanes)) { |
| 19050 | // This is not a sync update. Suspend. Since we're not activating a |
| 19051 | // Suspense boundary, this will unwind all the way to the root without |
| 19052 | // performing a second pass to render a fallback. (This is arguably how |
| 19053 | // refresh transitions should work, too, since we're not going to commit |
| 19054 | // the fallbacks anyway.) |
| 19055 | // |
| 19056 | // This case also applies to initial hydration. |
| 19057 | attachPingListener(root, wakeable, rootRenderLanes); |
| 19058 | renderDidSuspendDelayIfPossible(); |
| 19059 | return; |
| 19060 | } // This is a sync/discrete update. We treat this case like an error |
| 19061 | // because discrete renders are expected to produce a complete tree |
| 19062 | // synchronously to maintain consistency with external state. |
| 19063 | |
| 19064 | |
| 19065 | var uncaughtSuspenseError = new Error('A component suspended while responding to synchronous input. This ' + 'will cause the UI to be replaced with a loading indicator. To ' + 'fix, updates that suspend should be wrapped ' + 'with startTransition.'); // If we're outside a transition, fall through to the regular error path. |
| 19066 | // The error will be caught by the nearest suspense boundary. |
| 19067 |
no test coverage detected
searching dependent graphs…