@@ -140,6 +140,7 @@ import {
140
140
} from './ReactHookEffectTags' ;
141
141
import { didWarnAboutReassigningProps } from './ReactFiberBeginWork.new' ;
142
142
import { doesFiberContain } from './ReactFiberTreeReflection' ;
143
+ import { invokeGuardedCallback , clearCaughtError } from 'shared/ReactErrorUtils' ;
143
144
144
145
let didWarnAboutUndefinedSnapshotBeforeUpdate : Set < mixed > | null = null ;
145
146
if ( __DEV__ ) {
@@ -160,6 +161,20 @@ let nextEffect: Fiber | null = null;
160
161
let inProgressLanes : Lanes | null = null ;
161
162
let inProgressRoot : FiberRoot | null = null ;
162
163
164
+ function reportUncaughtErrorInDEV ( error ) {
165
+ // Wrapping each small part of the commit phase into a guarded
166
+ // callback is a bit too slow (https://github.com/facebook/react/pull/21666).
167
+ // But we rely on it to surface errors to DEV tools like overlays
168
+ // (https://github.com/facebook/react/issues/21712).
169
+ // As a compromise, rethrow only caught errors in a guard.
170
+ if ( __DEV__ ) {
171
+ invokeGuardedCallback ( null , ( ) => {
172
+ throw error ;
173
+ } ) ;
174
+ clearCaughtError ( ) ;
175
+ }
176
+ }
177
+
163
178
const callComponentWillUnmountWithTimer = function ( current , instance ) {
164
179
instance . props = current . memoizedProps ;
165
180
instance . state = current . memoizedState ;
@@ -186,8 +201,9 @@ function safelyCallCommitHookLayoutEffectListMount(
186
201
) {
187
202
try {
188
203
commitHookEffectListMount ( HookLayout , current ) ;
189
- } catch ( unmountError ) {
190
- captureCommitPhaseError ( current , nearestMountedAncestor , unmountError ) ;
204
+ } catch ( error ) {
205
+ reportUncaughtErrorInDEV ( error ) ;
206
+ captureCommitPhaseError ( current , nearestMountedAncestor , error ) ;
191
207
}
192
208
}
193
209
@@ -199,8 +215,9 @@ function safelyCallComponentWillUnmount(
199
215
) {
200
216
try {
201
217
callComponentWillUnmountWithTimer ( current , instance ) ;
202
- } catch ( unmountError ) {
203
- captureCommitPhaseError ( current , nearestMountedAncestor , unmountError ) ;
218
+ } catch ( error ) {
219
+ reportUncaughtErrorInDEV ( error ) ;
220
+ captureCommitPhaseError ( current , nearestMountedAncestor , error ) ;
204
221
}
205
222
}
206
223
@@ -212,17 +229,19 @@ function safelyCallComponentDidMount(
212
229
) {
213
230
try {
214
231
instance . componentDidMount ( ) ;
215
- } catch ( unmountError ) {
216
- captureCommitPhaseError ( current , nearestMountedAncestor , unmountError ) ;
232
+ } catch ( error ) {
233
+ reportUncaughtErrorInDEV ( error ) ;
234
+ captureCommitPhaseError ( current , nearestMountedAncestor , error ) ;
217
235
}
218
236
}
219
237
220
238
// Capture errors so they don't interrupt mounting.
221
239
function safelyAttachRef ( current : Fiber , nearestMountedAncestor : Fiber | null ) {
222
240
try {
223
241
commitAttachRef ( current ) ;
224
- } catch ( unmountError ) {
225
- captureCommitPhaseError ( current , nearestMountedAncestor , unmountError ) ;
242
+ } catch ( error ) {
243
+ reportUncaughtErrorInDEV ( error ) ;
244
+ captureCommitPhaseError ( current , nearestMountedAncestor , error ) ;
226
245
}
227
246
}
228
247
@@ -246,6 +265,7 @@ function safelyDetachRef(current: Fiber, nearestMountedAncestor: Fiber | null) {
246
265
ref ( null ) ;
247
266
}
248
267
} catch ( error ) {
268
+ reportUncaughtErrorInDEV ( error ) ;
249
269
captureCommitPhaseError ( current , nearestMountedAncestor , error ) ;
250
270
}
251
271
} else {
@@ -262,6 +282,7 @@ function safelyCallDestroy(
262
282
try {
263
283
destroy ( ) ;
264
284
} catch ( error ) {
285
+ reportUncaughtErrorInDEV ( error ) ;
265
286
captureCommitPhaseError ( current , nearestMountedAncestor , error ) ;
266
287
}
267
288
}
@@ -323,6 +344,7 @@ function commitBeforeMutationEffects_complete() {
323
344
try {
324
345
commitBeforeMutationEffectsOnFiber ( fiber ) ;
325
346
} catch ( error ) {
347
+ reportUncaughtErrorInDEV ( error ) ;
326
348
captureCommitPhaseError ( fiber , fiber . return , error ) ;
327
349
}
328
350
resetCurrentDebugFiberInDEV ( ) ;
@@ -2065,6 +2087,7 @@ function commitMutationEffects_begin(root: FiberRoot) {
2065
2087
try {
2066
2088
commitDeletion ( root , childToDelete , fiber ) ;
2067
2089
} catch ( error ) {
2090
+ reportUncaughtErrorInDEV ( error ) ;
2068
2091
captureCommitPhaseError ( childToDelete , fiber , error ) ;
2069
2092
}
2070
2093
}
@@ -2087,6 +2110,7 @@ function commitMutationEffects_complete(root: FiberRoot) {
2087
2110
try {
2088
2111
commitMutationEffectsOnFiber ( fiber , root ) ;
2089
2112
} catch ( error ) {
2113
+ reportUncaughtErrorInDEV ( error ) ;
2090
2114
captureCommitPhaseError ( fiber , fiber . return , error ) ;
2091
2115
}
2092
2116
resetCurrentDebugFiberInDEV ( ) ;
@@ -2329,6 +2353,7 @@ function commitLayoutMountEffects_complete(
2329
2353
try {
2330
2354
commitLayoutEffectOnFiber ( root , current , fiber , committedLanes ) ;
2331
2355
} catch ( error ) {
2356
+ reportUncaughtErrorInDEV ( error ) ;
2332
2357
captureCommitPhaseError ( fiber , fiber . return , error ) ;
2333
2358
}
2334
2359
resetCurrentDebugFiberInDEV ( ) ;
@@ -2382,6 +2407,7 @@ function commitPassiveMountEffects_complete(
2382
2407
try {
2383
2408
commitPassiveMountOnFiber ( root , fiber ) ;
2384
2409
} catch ( error ) {
2410
+ reportUncaughtErrorInDEV ( error ) ;
2385
2411
captureCommitPhaseError ( fiber , fiber . return , error ) ;
2386
2412
}
2387
2413
resetCurrentDebugFiberInDEV ( ) ;
@@ -2664,6 +2690,7 @@ function invokeLayoutEffectMountInDEV(fiber: Fiber): void {
2664
2690
try {
2665
2691
commitHookEffectListMount ( HookLayout | HookHasEffect , fiber ) ;
2666
2692
} catch ( error ) {
2693
+ reportUncaughtErrorInDEV ( error ) ;
2667
2694
captureCommitPhaseError ( fiber , fiber . return , error ) ;
2668
2695
}
2669
2696
break ;
@@ -2673,6 +2700,7 @@ function invokeLayoutEffectMountInDEV(fiber: Fiber): void {
2673
2700
try {
2674
2701
instance . componentDidMount ( ) ;
2675
2702
} catch ( error ) {
2703
+ reportUncaughtErrorInDEV ( error ) ;
2676
2704
captureCommitPhaseError ( fiber , fiber . return , error ) ;
2677
2705
}
2678
2706
break ;
@@ -2692,6 +2720,7 @@ function invokePassiveEffectMountInDEV(fiber: Fiber): void {
2692
2720
try {
2693
2721
commitHookEffectListMount ( HookPassive | HookHasEffect , fiber ) ;
2694
2722
} catch ( error ) {
2723
+ reportUncaughtErrorInDEV ( error ) ;
2695
2724
captureCommitPhaseError ( fiber , fiber . return , error ) ;
2696
2725
}
2697
2726
break ;
@@ -2715,6 +2744,7 @@ function invokeLayoutEffectUnmountInDEV(fiber: Fiber): void {
2715
2744
fiber . return ,
2716
2745
) ;
2717
2746
} catch ( error ) {
2747
+ reportUncaughtErrorInDEV ( error ) ;
2718
2748
captureCommitPhaseError ( fiber , fiber . return , error ) ;
2719
2749
}
2720
2750
break ;
@@ -2745,6 +2775,7 @@ function invokePassiveEffectUnmountInDEV(fiber: Fiber): void {
2745
2775
fiber . return ,
2746
2776
) ;
2747
2777
} catch ( error ) {
2778
+ reportUncaughtErrorInDEV ( error ) ;
2748
2779
captureCommitPhaseError ( fiber , fiber . return , error ) ;
2749
2780
}
2750
2781
}
0 commit comments