Skip to content

Commit cb1d1c0

Browse files
committed
Mark Errored Server Components
1 parent 518d06d commit cb1d1c0

File tree

2 files changed

+73
-8
lines changed

2 files changed

+73
-8
lines changed

packages/react-client/src/ReactFlightClient.js

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ import {
7373
markAllTracksInOrder,
7474
logComponentRender,
7575
logDedupedComponentRender,
76+
logComponentErrored,
7677
} from './ReactFlightPerformanceTrack';
7778

7879
import {
@@ -2876,6 +2877,7 @@ function flushComponentPerformance(
28762877

28772878
if (debugInfo) {
28782879
let endTime = 0;
2880+
let isLastComponent = true;
28792881
for (let i = debugInfo.length - 1; i >= 0; i--) {
28802882
const info = debugInfo[i];
28812883
if (typeof info.time === 'number') {
@@ -2890,17 +2892,37 @@ function flushComponentPerformance(
28902892
const startTimeInfo = debugInfo[i - 1];
28912893
if (typeof startTimeInfo.time === 'number') {
28922894
const startTime = startTimeInfo.time;
2893-
logComponentRender(
2894-
componentInfo,
2895-
trackIdx,
2896-
startTime,
2897-
endTime,
2898-
childrenEndTime,
2899-
response._rootEnvironmentName,
2900-
);
2895+
if (
2896+
isLastComponent &&
2897+
root.status === ERRORED &&
2898+
root.reason !== response._closedReason
2899+
) {
2900+
// If this is the last component to render before this chunk rejected, then conceptually
2901+
// this component errored. If this was a cancellation then it wasn't this component that
2902+
// errored.
2903+
logComponentErrored(
2904+
componentInfo,
2905+
trackIdx,
2906+
startTime,
2907+
endTime,
2908+
childrenEndTime,
2909+
response._rootEnvironmentName,
2910+
root.reason,
2911+
);
2912+
} else {
2913+
logComponentRender(
2914+
componentInfo,
2915+
trackIdx,
2916+
startTime,
2917+
endTime,
2918+
childrenEndTime,
2919+
response._rootEnvironmentName,
2920+
);
2921+
}
29012922
// Track the root most component of the result for deduping logging.
29022923
result.component = componentInfo;
29032924
}
2925+
isLastComponent = false;
29042926
}
29052927
}
29062928
}

packages/react-client/src/ReactFlightPerformanceTrack.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,49 @@ export function logComponentRender(
102102
}
103103
}
104104

105+
export function logComponentErrored(
106+
componentInfo: ReactComponentInfo,
107+
trackIdx: number,
108+
startTime: number,
109+
endTime: number,
110+
childrenEndTime: number,
111+
rootEnv: string,
112+
error: mixed,
113+
): void {
114+
if (supportsUserTiming) {
115+
const properties = [];
116+
if (__DEV__) {
117+
const message =
118+
typeof error === 'object' &&
119+
error !== null &&
120+
typeof error.message === 'string'
121+
? // eslint-disable-next-line react-internal/safe-string-coercion
122+
String(error.message)
123+
: // eslint-disable-next-line react-internal/safe-string-coercion
124+
String(error);
125+
properties.push(['Error', message]);
126+
}
127+
const env = componentInfo.env;
128+
const name = componentInfo.name;
129+
const isPrimaryEnv = env === rootEnv;
130+
const entryName =
131+
isPrimaryEnv || env === undefined ? name : name + ' [' + env + ']';
132+
performance.measure(entryName, {
133+
start: startTime < 0 ? 0 : startTime,
134+
end: childrenEndTime,
135+
detail: {
136+
devtools: {
137+
color: 'error',
138+
track: trackNames[trackIdx],
139+
trackGroup: COMPONENTS_TRACK,
140+
tooltipText: entryName + ' Errored',
141+
properties,
142+
},
143+
},
144+
});
145+
}
146+
}
147+
105148
export function logDedupedComponentRender(
106149
componentInfo: ReactComponentInfo,
107150
trackIdx: number,

0 commit comments

Comments
 (0)