Skip to content

Commit b44a99b

Browse files
authored
[Fiber] Name content inside "Suspense fallback" (#33724)
Same as #33723 but for Fiber.
1 parent e4314a0 commit b44a99b

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

packages/react-reconciler/src/ReactFiberComponentStack.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import {
3434
} from 'shared/ReactComponentStackFrame';
3535
import {formatOwnerStack} from 'shared/ReactOwnerStackFrames';
3636

37-
function describeFiber(fiber: Fiber): string {
37+
function describeFiber(fiber: Fiber, childFiber: null | Fiber): string {
3838
switch (fiber.tag) {
3939
case HostHoistable:
4040
case HostSingleton:
@@ -44,6 +44,10 @@ function describeFiber(fiber: Fiber): string {
4444
// TODO: When we support Thenables as component types we should rename this.
4545
return describeBuiltInComponentFrame('Lazy');
4646
case SuspenseComponent:
47+
if (fiber.child !== childFiber && childFiber !== null) {
48+
// If we came from the second Fiber then we're in the Suspense Fallback.
49+
return describeBuiltInComponentFrame('Suspense Fallback');
50+
}
4751
return describeBuiltInComponentFrame('Suspense');
4852
case SuspenseListComponent:
4953
return describeBuiltInComponentFrame('SuspenseList');
@@ -70,8 +74,9 @@ export function getStackByFiberInDevAndProd(workInProgress: Fiber): string {
7074
try {
7175
let info = '';
7276
let node: Fiber = workInProgress;
77+
let previous: null | Fiber = null;
7378
do {
74-
info += describeFiber(node);
79+
info += describeFiber(node, previous);
7580
if (__DEV__) {
7681
// Add any Server Component stack frames in reverse order.
7782
const debugInfo = node._debugInfo;
@@ -88,6 +93,7 @@ export function getStackByFiberInDevAndProd(workInProgress: Fiber): string {
8893
}
8994
}
9095
}
96+
previous = node;
9197
// $FlowFixMe[incompatible-type] we bail out when we get a null
9298
node = node.return;
9399
} while (node);

packages/react-reconciler/src/__tests__/ReactErrorStacks-test.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ describe('ReactFragment', () => {
8787
function normalizeCodeLocInfo(str) {
8888
return (
8989
str &&
90-
str.replace(/\n +(?:at|in) ([\S]+)[^\n]*/g, function (m, name) {
90+
str.replace(/\n +(?:at|in) ([^\(]+) [^\n]*/g, function (m, name) {
9191
return '\n in ' + name + ' (at **)';
9292
})
9393
);
@@ -168,6 +168,40 @@ describe('ReactFragment', () => {
168168
]);
169169
});
170170

171+
it('includes built-in for Suspense fallbacks', async () => {
172+
const SomethingThatSuspends = React.lazy(() => {
173+
return new Promise(() => {});
174+
});
175+
176+
ReactNoop.createRoot({
177+
onCaughtError,
178+
}).render(
179+
<CatchingBoundary>
180+
<Suspense fallback={<SomethingThatErrors />}>
181+
<SomethingThatSuspends />
182+
</Suspense>
183+
</CatchingBoundary>,
184+
);
185+
await waitForAll([]);
186+
expect(didCatchErrors).toEqual([
187+
'uh oh',
188+
componentStack([
189+
'SomethingThatErrors',
190+
'Suspense Fallback',
191+
'CatchingBoundary',
192+
]),
193+
]);
194+
expect(rootCaughtErrors).toEqual([
195+
'uh oh',
196+
componentStack([
197+
'SomethingThatErrors',
198+
'Suspense Fallback',
199+
'CatchingBoundary',
200+
]),
201+
__DEV__ ? componentStack(['SomethingThatErrors']) : null,
202+
]);
203+
});
204+
171205
// @gate enableActivity
172206
it('includes built-in for Activity', async () => {
173207
ReactNoop.createRoot({

0 commit comments

Comments
 (0)