Skip to content

Commit df783f9

Browse files
authored
Add unknown location information to component stacks (#30290)
This is the same change as in #30289 but for the main runtime - e.g. parent stacks in errorInfo.componentStack, appended stacks to console.error coming from React itself and when we add virtual frames to owner stacks. Since we don't add location information these frames look weird to some stack parsers - such as the native one. This is an existing issue when you want to use some off-the-shelf parsers to parse production component stacks for example. While we won't add Error objects to logs ourselves necessarily, some third party could want to do the same thing we do in DevTools and so we should provide the same capability to just take this trace and print it using an Error object.
1 parent 1b0132c commit df783f9

File tree

3 files changed

+14
-4
lines changed

3 files changed

+14
-4
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ describe('ReactDOM HostSingleton', () => {
475475
expect(hydrationErrors).toEqual([
476476
[
477477
"Hydration failed because the server rendered HTML didn't match the client.",
478-
'at div',
478+
'at div (<anonymous>)',
479479
],
480480
]);
481481
expect(persistentElements).toEqual([

packages/react-server/src/ReactFizzServer.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,7 @@ function pushServerComponentStack(
924924
let name = componentInfo.name;
925925
const env = componentInfo.env;
926926
if (env) {
927-
name += ' (' + env + ')';
927+
name += ' [' + env + ']';
928928
}
929929
task.componentStack = {
930930
tag: 3,

packages/shared/ReactComponentStackFrame.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {disableLogs, reenableLogs} from 'shared/ConsolePatchingDev';
2424
import ReactSharedInternals from 'shared/ReactSharedInternals';
2525

2626
let prefix;
27+
let suffix;
2728
export function describeBuiltInComponentFrame(name: string): string {
2829
if (enableComponentStackLocations) {
2930
if (prefix === undefined) {
@@ -33,17 +34,26 @@ export function describeBuiltInComponentFrame(name: string): string {
3334
} catch (x) {
3435
const match = x.stack.trim().match(/\n( *(at )?)/);
3536
prefix = (match && match[1]) || '';
37+
suffix =
38+
x.stack.indexOf('\n at') > -1
39+
? // V8
40+
' (<anonymous>)'
41+
: // JSC/Spidermonkey
42+
x.stack.indexOf('@') > -1
43+
? '@unknown:0:0'
44+
: // Other
45+
'';
3646
}
3747
}
3848
// We use the prefix to ensure our stacks line up with native stack frames.
39-
return '\n' + prefix + name;
49+
return '\n' + prefix + name + suffix;
4050
} else {
4151
return describeComponentFrame(name);
4252
}
4353
}
4454

4555
export function describeDebugInfoFrame(name: string, env: ?string): string {
46-
return describeBuiltInComponentFrame(name + (env ? ' (' + env + ')' : ''));
56+
return describeBuiltInComponentFrame(name + (env ? ' [' + env + ']' : ''));
4757
}
4858

4959
let reentry = false;

0 commit comments

Comments
 (0)