98
Cloned,
99
PerformedWork,
100
ForceClientRender,
101
+ DidCapture,
102
} from './ReactFiberFlags';
103
import {
104
commitStartTime,
108
resetComponentEffectTimers,
109
pushComponentEffectStart,
110
popComponentEffectStart,
111
+ pushComponentEffectErrors,
112
+ popComponentEffectErrors,
113
componentEffectStartTime,
114
componentEffectEndTime,
115
componentEffectDuration,
116
+ componentEffectErrors,
117
} from './ReactProfilerTimer';
118
import {
119
logComponentRender,
120
+ logComponentErrored,
121
logComponentEffect,
117
- logSuspenseBoundaryClientRendered,
122
} from './ReactFiberPerformanceTrack';
123
import {ConcurrentMode, NoMode, ProfileMode} from './ReactTypeOfMode';
124
import {deferHiddenCallbacks} from './ReactFiberClassUpdateQueue';
399
committedLanes: Lanes,
400
): void {
401
const prevEffectStart = pushComponentEffectStart();
398
-
402
+ const prevEffectErrors = pushComponentEffectErrors();
403
// When updating this function, also update reappearLayoutEffects, which does
404
// most of the same things when an offscreen tree goes from hidden -> visible.
405
const flags = finishedWork.flags;
635
componentEffectStartTime,
636
componentEffectEndTime,
637
componentEffectDuration,
638
+ componentEffectErrors,
639
);
640
}
641
642
popComponentEffectStart(prevEffectStart);
643
+ popComponentEffectErrors(prevEffectErrors);
644
}
645
646
function abortRootTransitions(
1633
lanes: Lanes,
1634
) {
1635
const prevEffectStart = pushComponentEffectStart();
1630
-
1636
+ const prevEffectErrors = pushComponentEffectErrors();
1637
const current = finishedWork.alternate;
1638
const flags = finishedWork.flags;
1639
2142
componentEffectStartTime,
2143
componentEffectEndTime,
2144
componentEffectDuration,
2145
+ componentEffectErrors,
2146
);
2147
}
2148
2149
popComponentEffectStart(prevEffectStart);
2150
+ popComponentEffectErrors(prevEffectErrors);
2151
}
2152
2153
function commitReconciliationEffects(finishedWork: Fiber) {
2220
2221
export function disappearLayoutEffects(finishedWork: Fiber) {
2222
const prevEffectStart = pushComponentEffectStart();
2215
-
2223
+ const prevEffectErrors = pushComponentEffectErrors();
2224
switch (finishedWork.tag) {
2225
case FunctionComponent:
2226
case ForwardRef:
2293
componentEffectStartTime,
2294
componentEffectEndTime,
2295
componentEffectDuration,
2296
+ componentEffectErrors,
2297
);
2298
}
2299
2300
popComponentEffectStart(prevEffectStart);
2301
+ popComponentEffectErrors(prevEffectErrors);
2302
}
2303
2304
function recursivelyTraverseDisappearLayoutEffects(parentFiber: Fiber) {
2320
includeWorkInProgressEffects: boolean,
2321
) {
2322
const prevEffectStart = pushComponentEffectStart();
2313
-
2323
+ const prevEffectErrors = pushComponentEffectErrors();
2324
// Turn on layout effects in a tree that previously disappeared.
2325
const flags = finishedWork.flags;
2326
switch (finishedWork.tag) {
2471
componentEffectStartTime,
2472
componentEffectEndTime,
2473
componentEffectDuration,
2474
+ componentEffectErrors,
2475
);
2476
}
2477
2478
popComponentEffectStart(prevEffectStart);
2479
+ popComponentEffectErrors(prevEffectErrors);
2480
}
2481
2482
function recursivelyTraverseReappearLayoutEffects(
2713
endTime: number, // Profiling-only. The start time of the next Fiber or root completion.
2714
): void {
2715
const prevEffectStart = pushComponentEffectStart();
2704
-
2705
- // If this component rendered in Profiling mode (DEV or in Profiler component) then log its
2706
- // render time. We do this after the fact in the passive effect to avoid the overhead of this
2707
- // getting in the way of the render characteristics and avoid the overhead of unwinding
2708
- // uncommitted renders.
2709
- if (
2710
- enableProfilerTimer &&
2711
- enableComponentPerformanceTrack &&
2712
- (finishedWork.mode & ProfileMode) !== NoMode &&
2713
- ((finishedWork.actualStartTime: any): number) > 0 &&
2714
- (finishedWork.flags & PerformedWork) !== NoFlags
2715
- ) {
2716
- logComponentRender(
2717
- finishedWork,
2718
- ((finishedWork.actualStartTime: any): number),
2719
- endTime,
2720
- inHydratedSubtree,
2721
- );
2722
- }
2723
-
2716
+ const prevEffectErrors = pushComponentEffectErrors();
2717
// When updating this function, also update reconnectPassiveEffects, which does
2718
// most of the same things when an offscreen tree goes from hidden -> visible,
2719
// or when toggling effects inside a hidden tree.
2722
case FunctionComponent:
2723
case ForwardRef:
2724
case SimpleMemoComponent: {
2725
+ // If this component rendered in Profiling mode (DEV or in Profiler component) then log its
2726
+ // render time. We do this after the fact in the passive effect to avoid the overhead of this
2727
+ // getting in the way of the render characteristics and avoid the overhead of unwinding
2728
+ // uncommitted renders.
2729
+ if (
2730
+ enableProfilerTimer &&
2731
+ enableComponentPerformanceTrack &&
2732
+ (finishedWork.mode & ProfileMode) !== NoMode &&
2733
+ ((finishedWork.actualStartTime: any): number) > 0 &&
2734
+ (finishedWork.flags & PerformedWork) !== NoFlags
2735
+ ) {
2736
+ logComponentRender(
2737
+ finishedWork,
2738
+ ((finishedWork.actualStartTime: any): number),
2739
+ endTime,
2740
+ inHydratedSubtree,
2741
+ );
2742
+ }
2743
+
2744
recursivelyTraversePassiveMountEffects(
2745
finishedRoot,
2746
finishedWork,
2756
}
2757
break;
2758
}
2759
+ case ClassComponent: {
2760
+ // If this component rendered in Profiling mode (DEV or in Profiler component) then log its
2761
+ // render time. We do this after the fact in the passive effect to avoid the overhead of this
2762
+ // getting in the way of the render characteristics and avoid the overhead of unwinding
2763
+ // uncommitted renders.
2764
+ if (
2765
+ enableProfilerTimer &&
2766
+ enableComponentPerformanceTrack &&
2767
+ (finishedWork.mode & ProfileMode) !== NoMode &&
2768
+ ((finishedWork.actualStartTime: any): number) > 0
2769
+ ) {
2770
+ if ((finishedWork.flags & DidCapture) !== NoFlags) {
2771
+ logComponentErrored(
2772
+ finishedWork,
2773
+ ((finishedWork.actualStartTime: any): number),
2774
+ endTime,
2775
+ // TODO: The captured values are all hidden inside the updater/callback closures so
2776
+ // we can't get to the errors but they're there so we should be able to log them.
2777
+ [],
2778
+ );
2779
+ } else if ((finishedWork.flags & PerformedWork) !== NoFlags) {
2780
+ logComponentRender(
2781
+ finishedWork,
2782
+ ((finishedWork.actualStartTime: any): number),
2783
+ endTime,
2784
+ inHydratedSubtree,
2785
+ );
2786
+ }
2787
+ }
2788
+
2789
+ recursivelyTraversePassiveMountEffects(
2790
+ finishedRoot,
2791
+ finishedWork,
2792
+ committedLanes,
2793
+ committedTransitions,
2794
+ endTime,
2795
+ );
2796
+ break;
2797
+ }
2798
case HostRoot: {
2799
const prevEffectDuration = pushNestedEffectDurations();
2800
2942
// rendered boundary. Such as postpone.
2943
if (hydrationErrors !== null) {
2944
const startTime: number = (finishedWork.actualStartTime: any);
2894
- logSuspenseBoundaryClientRendered(
2945
+ logComponentErrored(
2946
finishedWork,
2947
startTime,
2948
endTime,
3125
componentEffectStartTime,
3126
componentEffectEndTime,
3127
componentEffectDuration,
3128
+ componentEffectErrors,
3129
);
3130
}
3131
3132
popComponentEffectStart(prevEffectStart);
3133
+ popComponentEffectErrors(prevEffectErrors);
3134
}
3135
3136
function recursivelyTraverseReconnectPassiveEffects(
3190
endTime: number, // Profiling-only. The start time of the next Fiber or root completion.
3191
) {
3192
const prevEffectStart = pushComponentEffectStart();
3140
-
3193
+ const prevEffectErrors = pushComponentEffectErrors();
3194
// If this component rendered in Profiling mode (DEV or in Profiler component) then log its
3195
// render time. We do this after the fact in the passive effect to avoid the overhead of this
3196
// getting in the way of the render characteristics and avoid the overhead of unwinding
3384
componentEffectStartTime,
3385
componentEffectEndTime,
3386
componentEffectDuration,
3387
+ componentEffectErrors,
3388
);
3389
}
3390
3391
popComponentEffectStart(prevEffectStart);
3392
+ popComponentEffectErrors(prevEffectErrors);
3393
}
3394
3395
function recursivelyTraverseAtomicPassiveEffects(
3666
3667
function commitPassiveUnmountOnFiber(finishedWork: Fiber): void {
3668
const prevEffectStart = pushComponentEffectStart();
3614
-
3669
+ const prevEffectErrors = pushComponentEffectErrors();
3670
switch (finishedWork.tag) {
3671
case FunctionComponent:
3672
case ForwardRef:
3751
componentEffectStartTime,
3752
componentEffectEndTime,
3753
componentEffectDuration,
3754
+ componentEffectErrors,
3755
);
3756
}
3757
3758
popComponentEffectStart(prevEffectStart);
3759
+ popComponentEffectErrors(prevEffectErrors);
3760
}
3761
3762
function recursivelyTraverseDisconnectPassiveEffects(parentFiber: Fiber): void {
3876
nearestMountedAncestor: Fiber | null,
3877
): void {
3878
const prevEffectStart = pushComponentEffectStart();
3822
-
3879
+ const prevEffectErrors = pushComponentEffectErrors();
3880
switch (current.tag) {
3881
case FunctionComponent:
3882
case ForwardRef:
4003
componentEffectStartTime,
4004
componentEffectEndTime,
4005
componentEffectDuration,
4006
+ componentEffectErrors,
4007
);
4008
}
4009
4010
popComponentEffectStart(prevEffectStart);
4011
+ popComponentEffectErrors(prevEffectErrors);
4012
}
4013
4014
export function invokeLayoutEffectMountInDEV(fiber: Fiber): void {