@@ -688,7 +688,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
688
688
workLoopConcurrent ( ) ;
689
689
break ;
690
690
} catch ( thrownValue ) {
691
- handleError ( root , workInProgress , thrownValue ) ;
691
+ handleError ( root , thrownValue ) ;
692
692
}
693
693
} while ( true ) ;
694
694
resetContextDependencies ( ) ;
@@ -1031,7 +1031,7 @@ function performSyncWorkOnRoot(root) {
1031
1031
workLoopSync ( ) ;
1032
1032
break ;
1033
1033
} catch ( thrownValue ) {
1034
- handleError ( root , workInProgress , thrownValue ) ;
1034
+ handleError ( root , thrownValue ) ;
1035
1035
}
1036
1036
} while ( true ) ;
1037
1037
resetContextDependencies ( ) ;
@@ -1322,38 +1322,46 @@ function prepareFreshStack(root, expirationTime) {
1322
1322
}
1323
1323
}
1324
1324
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 ( ) ;
1329
1331
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
+ }
1339
1341
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
+ }
1346
1348
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 ) ;
1357
1365
}
1358
1366
1359
1367
function pushDispatcher ( root ) {
0 commit comments