(root, returnFiber, sourceFiber, value, renderExpirationTime)
| 20934 | } |
| 20935 | |
| 20936 | function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) { |
| 20937 | // The source fiber did not complete. |
| 20938 | sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid. |
| 20939 | |
| 20940 | sourceFiber.firstEffect = sourceFiber.lastEffect = null; |
| 20941 | |
| 20942 | if (value !== null && typeof value === 'object' && typeof value.then === 'function') { |
| 20943 | // This is a thenable. |
| 20944 | var thenable = value; |
| 20945 | |
| 20946 | if ((sourceFiber.mode & BlockingMode) === NoMode) { |
| 20947 | // Reset the memoizedState to what it was before we attempted |
| 20948 | // to render it. |
| 20949 | var currentSource = sourceFiber.alternate; |
| 20950 | |
| 20951 | if (currentSource) { |
| 20952 | sourceFiber.updateQueue = currentSource.updateQueue; |
| 20953 | sourceFiber.memoizedState = currentSource.memoizedState; |
| 20954 | sourceFiber.expirationTime = currentSource.expirationTime; |
| 20955 | } else { |
| 20956 | sourceFiber.updateQueue = null; |
| 20957 | sourceFiber.memoizedState = null; |
| 20958 | } |
| 20959 | } |
| 20960 | |
| 20961 | var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view. |
| 20962 | |
| 20963 | var _workInProgress = returnFiber; |
| 20964 | |
| 20965 | do { |
| 20966 | if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) { |
| 20967 | // Found the nearest boundary. |
| 20968 | // Stash the promise on the boundary fiber. If the boundary times out, we'll |
| 20969 | // attach another listener to flip the boundary back to its normal state. |
| 20970 | var thenables = _workInProgress.updateQueue; |
| 20971 | |
| 20972 | if (thenables === null) { |
| 20973 | var updateQueue = new Set(); |
| 20974 | updateQueue.add(thenable); |
| 20975 | _workInProgress.updateQueue = updateQueue; |
| 20976 | } else { |
| 20977 | thenables.add(thenable); |
| 20978 | } // If the boundary is outside of blocking mode, we should *not* |
| 20979 | // suspend the commit. Pretend as if the suspended component rendered |
| 20980 | // null and keep rendering. In the commit phase, we'll schedule a |
| 20981 | // subsequent synchronous update to re-render the Suspense. |
| 20982 | // |
| 20983 | // Note: It doesn't matter whether the component that suspended was |
| 20984 | // inside a blocking mode tree. If the Suspense is outside of it, we |
| 20985 | // should *not* suspend the commit. |
| 20986 | |
| 20987 | |
| 20988 | if ((_workInProgress.mode & BlockingMode) === NoMode) { |
| 20989 | _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete. |
| 20990 | // But we shouldn't call any lifecycle methods or callbacks. Remove |
| 20991 | // all lifecycle effect tags. |
| 20992 | |
| 20993 | sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete); |
no test coverage detected