@@ -688,7 +688,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
688688 workLoopConcurrent ( ) ;
689689 break ;
690690 } catch ( thrownValue ) {
691- handleError ( root , workInProgress , thrownValue ) ;
691+ handleError ( root , thrownValue ) ;
692692 }
693693 } while ( true ) ;
694694 resetContextDependencies ( ) ;
@@ -1031,7 +1031,7 @@ function performSyncWorkOnRoot(root) {
10311031 workLoopSync ( ) ;
10321032 break ;
10331033 } catch ( thrownValue ) {
1034- handleError ( root , workInProgress , thrownValue ) ;
1034+ handleError ( root , thrownValue ) ;
10351035 }
10361036 } while ( true ) ;
10371037 resetContextDependencies ( ) ;
@@ -1322,38 +1322,46 @@ function prepareFreshStack(root, expirationTime) {
13221322 }
13231323}
13241324
1325- function handleError ( root , sourceFiber , thrownValue ) {
1326- // Reset module-level state that was set during the render phase.
1327- resetContextDependencies ( ) ;
1328- resetHooks ( ) ;
1325+ function handleError ( root , thrownValue ) {
1326+ do {
1327+ try {
1328+ // Reset module-level state that was set during the render phase.
1329+ resetContextDependencies ( ) ;
1330+ resetHooks ( ) ;
13291331
1330- if ( workInProgress === null || workInProgress . return === null ) {
1331- // Expected to be working on a non-root fiber. This is a fatal error
1332- // because there's no ancestor that can handle it; the root is
1333- // supposed to capture all errors that weren't caught by an error
1334- // boundary.
1335- workInProgressRootExitStatus = RootFatalErrored ;
1336- workInProgressRootFatalError = thrownValue ;
1337- return null ;
1338- }
1332+ if ( workInProgress === null || workInProgress . return === null ) {
1333+ // Expected to be working on a non-root fiber. This is a fatal error
1334+ // because there's no ancestor that can handle it; the root is
1335+ // supposed to capture all errors that weren't caught by an error
1336+ // boundary.
1337+ workInProgressRootExitStatus = RootFatalErrored ;
1338+ workInProgressRootFatalError = thrownValue ;
1339+ return null ;
1340+ }
13391341
1340- if ( enableProfilerTimer && sourceFiber . mode & ProfileMode ) {
1341- // Record the time spent rendering before an error was thrown. This
1342- // avoids inaccurate Profiler durations in the case of a
1343- // suspended render.
1344- stopProfilerTimerIfRunningAndRecordDelta ( sourceFiber , true ) ;
1345- }
1342+ if ( enableProfilerTimer && workInProgress . mode & ProfileMode ) {
1343+ // Record the time spent rendering before an error was thrown. This
1344+ // avoids inaccurate Profiler durations in the case of a
1345+ // suspended render.
1346+ stopProfilerTimerIfRunningAndRecordDelta ( workInProgress , true ) ;
1347+ }
13461348
1347- throwException (
1348- root ,
1349- workInProgress . return ,
1350- sourceFiber ,
1351- thrownValue ,
1352- renderExpirationTime ,
1353- ) ;
1354- // TODO: This is not wrapped in a try-catch, so if the complete phase
1355- // throws, we won't capture it.
1356- workInProgress = completeUnitOfWork ( sourceFiber ) ;
1349+ throwException (
1350+ root ,
1351+ workInProgress . return ,
1352+ workInProgress ,
1353+ thrownValue ,
1354+ renderExpirationTime ,
1355+ ) ;
1356+ workInProgress = completeUnitOfWork ( workInProgress ) ;
1357+ } catch ( yetAnotherThrownValue ) {
1358+ // Something in the return path also threw.
1359+ thrownValue = yetAnotherThrownValue ;
1360+ continue ;
1361+ }
1362+ // Return to the normal work loop.
1363+ return ;
1364+ } while ( true ) ;
13571365}
13581366
13591367function pushDispatcher ( root ) {
0 commit comments