Skip to content

Commit 534c9c5

Browse files
authored
Move error logging to update callback (#21737)
* Move error logging to update callback This prevents double logging for gDSFE boundaries with createRoot. * Add an explanation for the rest of duplicates
1 parent 51b0bec commit 534c9c5

File tree

3 files changed

+23
-33
lines changed

3 files changed

+23
-33
lines changed

packages/react-dom/src/__tests__/ReactDOMConsoleErrorReporting-test.js

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ describe('ReactDOMConsoleErrorReporting', () => {
166166
}),
167167
],
168168
[
169-
// TODO: This is duplicated only with createRoot. Why?
169+
// This is only duplicated with createRoot
170+
// because it retries once with a sync render.
170171
expect.objectContaining({
171172
message: 'Boom',
172173
}),
@@ -181,7 +182,8 @@ describe('ReactDOMConsoleErrorReporting', () => {
181182
}),
182183
],
183184
[
184-
// TODO: This is duplicated only with createRoot. Why?
185+
// This is only duplicated with createRoot
186+
// because it retries once with a sync render.
185187
expect.stringContaining('Error: Uncaught [Error: Boom]'),
186188
expect.objectContaining({
187189
message: 'Boom',
@@ -246,7 +248,8 @@ describe('ReactDOMConsoleErrorReporting', () => {
246248
}),
247249
],
248250
[
249-
// TODO: This is duplicated only with createRoot. Why?
251+
// This is only duplicated with createRoot
252+
// because it retries once with a sync render.
250253
expect.objectContaining({
251254
message: 'Boom',
252255
}),
@@ -261,20 +264,15 @@ describe('ReactDOMConsoleErrorReporting', () => {
261264
}),
262265
],
263266
[
264-
// Addendum by React:
265-
expect.stringContaining(
266-
'The above error occurred in the <Foo> component',
267-
),
268-
],
269-
[
270-
// TODO: This is duplicated only with createRoot. Why?
267+
// This is only duplicated with createRoot
268+
// because it retries once with a sync render.
271269
expect.stringContaining('Error: Uncaught [Error: Boom]'),
272270
expect.objectContaining({
273271
message: 'Boom',
274272
}),
275273
],
276274
[
277-
// TODO: This is duplicated only with createRoot. Why?
275+
// Addendum by React:
278276
expect.stringContaining(
279277
'The above error occurred in the <Foo> component',
280278
),
@@ -291,12 +289,6 @@ describe('ReactDOMConsoleErrorReporting', () => {
291289
message: 'Boom',
292290
}),
293291
],
294-
[
295-
// TODO: This is duplicated only with createRoot. Why?
296-
expect.objectContaining({
297-
message: 'Boom',
298-
}),
299-
],
300292
]);
301293
}
302294

packages/react-reconciler/src/ReactFiberThrow.new.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,14 @@ function createClassErrorUpdate(
108108
if (typeof getDerivedStateFromError === 'function') {
109109
const error = errorInfo.value;
110110
update.payload = () => {
111-
logCapturedError(fiber, errorInfo);
112111
return getDerivedStateFromError(error);
113112
};
113+
update.callback = () => {
114+
if (__DEV__) {
115+
markFailedErrorBoundaryForHotReloading(fiber);
116+
}
117+
logCapturedError(fiber, errorInfo);
118+
};
114119
}
115120

116121
const inst = fiber.stateNode;
@@ -119,16 +124,14 @@ function createClassErrorUpdate(
119124
if (__DEV__) {
120125
markFailedErrorBoundaryForHotReloading(fiber);
121126
}
127+
logCapturedError(fiber, errorInfo);
122128
if (typeof getDerivedStateFromError !== 'function') {
123129
// To preserve the preexisting retry behavior of error boundaries,
124130
// we keep track of which ones already failed during this batch.
125131
// This gets reset before we yield back to the browser.
126132
// TODO: Warn in strict mode if getDerivedStateFromError is
127133
// not defined.
128134
markLegacyErrorBoundaryAsFailed(this);
129-
130-
// Only log here if componentDidCatch is the only error boundary method defined
131-
logCapturedError(fiber, errorInfo);
132135
}
133136
const error = errorInfo.value;
134137
const stack = errorInfo.stack;
@@ -150,10 +153,6 @@ function createClassErrorUpdate(
150153
}
151154
}
152155
};
153-
} else if (__DEV__) {
154-
update.callback = () => {
155-
markFailedErrorBoundaryForHotReloading(fiber);
156-
};
157156
}
158157
return update;
159158
}

packages/react-reconciler/src/ReactFiberThrow.old.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,14 @@ function createClassErrorUpdate(
108108
if (typeof getDerivedStateFromError === 'function') {
109109
const error = errorInfo.value;
110110
update.payload = () => {
111-
logCapturedError(fiber, errorInfo);
112111
return getDerivedStateFromError(error);
113112
};
113+
update.callback = () => {
114+
if (__DEV__) {
115+
markFailedErrorBoundaryForHotReloading(fiber);
116+
}
117+
logCapturedError(fiber, errorInfo);
118+
};
114119
}
115120

116121
const inst = fiber.stateNode;
@@ -119,16 +124,14 @@ function createClassErrorUpdate(
119124
if (__DEV__) {
120125
markFailedErrorBoundaryForHotReloading(fiber);
121126
}
127+
logCapturedError(fiber, errorInfo);
122128
if (typeof getDerivedStateFromError !== 'function') {
123129
// To preserve the preexisting retry behavior of error boundaries,
124130
// we keep track of which ones already failed during this batch.
125131
// This gets reset before we yield back to the browser.
126132
// TODO: Warn in strict mode if getDerivedStateFromError is
127133
// not defined.
128134
markLegacyErrorBoundaryAsFailed(this);
129-
130-
// Only log here if componentDidCatch is the only error boundary method defined
131-
logCapturedError(fiber, errorInfo);
132135
}
133136
const error = errorInfo.value;
134137
const stack = errorInfo.stack;
@@ -150,10 +153,6 @@ function createClassErrorUpdate(
150153
}
151154
}
152155
};
153-
} else if (__DEV__) {
154-
update.callback = () => {
155-
markFailedErrorBoundaryForHotReloading(fiber);
156-
};
157156
}
158157
return update;
159158
}

0 commit comments

Comments
 (0)