(root, returnFiber, sourceFiber, value, renderExpirationTime)
| 17811 | } |
| 17812 | |
| 17813 | function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) { |
| 17814 | // The source fiber did not complete. |
| 17815 | sourceFiber.effectTag |= Incomplete; |
| 17816 | // Its effect list is no longer valid. |
| 17817 | sourceFiber.firstEffect = sourceFiber.lastEffect = null; |
| 17818 | |
| 17819 | if (value !== null && typeof value === 'object' && typeof value.then === 'function') { |
| 17820 | // This is a thenable. |
| 17821 | var thenable = value; |
| 17822 | |
| 17823 | // Find the earliest timeout threshold of all the placeholders in the |
| 17824 | // ancestor path. We could avoid this traversal by storing the thresholds on |
| 17825 | // the stack, but we choose not to because we only hit this path if we're |
| 17826 | // IO-bound (i.e. if something suspends). Whereas the stack is used even in |
| 17827 | // the non-IO- bound case. |
| 17828 | var _workInProgress = returnFiber; |
| 17829 | var earliestTimeoutMs = -1; |
| 17830 | var startTimeMs = -1; |
| 17831 | do { |
| 17832 | if (_workInProgress.tag === SuspenseComponent) { |
| 17833 | var current$$1 = _workInProgress.alternate; |
| 17834 | if (current$$1 !== null) { |
| 17835 | var currentState = current$$1.memoizedState; |
| 17836 | if (currentState !== null) { |
| 17837 | // Reached a boundary that already timed out. Do not search |
| 17838 | // any further. |
| 17839 | var timedOutAt = currentState.timedOutAt; |
| 17840 | startTimeMs = expirationTimeToMs(timedOutAt); |
| 17841 | // Do not search any further. |
| 17842 | break; |
| 17843 | } |
| 17844 | } |
| 17845 | var timeoutPropMs = _workInProgress.pendingProps.maxDuration; |
| 17846 | if (typeof timeoutPropMs === 'number') { |
| 17847 | if (timeoutPropMs <= 0) { |
| 17848 | earliestTimeoutMs = 0; |
| 17849 | } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) { |
| 17850 | earliestTimeoutMs = timeoutPropMs; |
| 17851 | } |
| 17852 | } |
| 17853 | } |
| 17854 | _workInProgress = _workInProgress.return; |
| 17855 | } while (_workInProgress !== null); |
| 17856 | |
| 17857 | // Schedule the nearest Suspense to re-render the timed out view. |
| 17858 | _workInProgress = returnFiber; |
| 17859 | do { |
| 17860 | if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) { |
| 17861 | // Found the nearest boundary. |
| 17862 | |
| 17863 | // Stash the promise on the boundary fiber. If the boundary times out, we'll |
| 17864 | var thenables = _workInProgress.updateQueue; |
| 17865 | if (thenables === null) { |
| 17866 | _workInProgress.updateQueue = new Set([thenable]); |
| 17867 | } else { |
| 17868 | thenables.add(thenable); |
| 17869 | } |
| 17870 |
no test coverage detected