(root, returnFiber, sourceFiber, value, renderExpirationTime)
| 24494 | } |
| 24495 | |
| 24496 | function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) { |
| 24497 | // The source fiber did not complete. |
| 24498 | sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid. |
| 24499 | |
| 24500 | sourceFiber.firstEffect = sourceFiber.lastEffect = null; |
| 24501 | |
| 24502 | if (value !== null && typeof value === 'object' && typeof value.then === 'function') { |
| 24503 | // This is a thenable. |
| 24504 | var thenable = value; |
| 24505 | |
| 24506 | if ((sourceFiber.mode & BlockingMode) === NoMode) { |
| 24507 | // Reset the memoizedState to what it was before we attempted |
| 24508 | // to render it. |
| 24509 | var currentSource = sourceFiber.alternate; |
| 24510 | |
| 24511 | if (currentSource) { |
| 24512 | sourceFiber.updateQueue = currentSource.updateQueue; |
| 24513 | sourceFiber.memoizedState = currentSource.memoizedState; |
| 24514 | sourceFiber.expirationTime = currentSource.expirationTime; |
| 24515 | } else { |
| 24516 | sourceFiber.updateQueue = null; |
| 24517 | sourceFiber.memoizedState = null; |
| 24518 | } |
| 24519 | } |
| 24520 | |
| 24521 | var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view. |
| 24522 | |
| 24523 | var _workInProgress = returnFiber; |
| 24524 | |
| 24525 | do { |
| 24526 | if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) { |
| 24527 | // Found the nearest boundary. |
| 24528 | // Stash the promise on the boundary fiber. If the boundary times out, we'll |
| 24529 | // attach another listener to flip the boundary back to its normal state. |
| 24530 | var thenables = _workInProgress.updateQueue; |
| 24531 | |
| 24532 | if (thenables === null) { |
| 24533 | var updateQueue = new Set(); |
| 24534 | updateQueue.add(thenable); |
| 24535 | _workInProgress.updateQueue = updateQueue; |
| 24536 | } else { |
| 24537 | thenables.add(thenable); |
| 24538 | } // If the boundary is outside of blocking mode, we should *not* |
| 24539 | // suspend the commit. Pretend as if the suspended component rendered |
| 24540 | // null and keep rendering. In the commit phase, we'll schedule a |
| 24541 | // subsequent synchronous update to re-render the Suspense. |
| 24542 | // |
| 24543 | // Note: It doesn't matter whether the component that suspended was |
| 24544 | // inside a blocking mode tree. If the Suspense is outside of it, we |
| 24545 | // should *not* suspend the commit. |
| 24546 | |
| 24547 | |
| 24548 | if ((_workInProgress.mode & BlockingMode) === NoMode) { |
| 24549 | _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete. |
| 24550 | // But we shouldn't call any lifecycle methods or callbacks. Remove |
| 24551 | // all lifecycle effect tags. |
| 24552 | |
| 24553 | sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete); |
no test coverage detected