Skip to content

Commit 50be937

Browse files
committed
[Fiber] Enable Native console.createTask Stacks When Available (#29223)
Stacked on #29206 and #29221. This disables appending owner stacks to console when `console.createTask` is available in the environment. Instead we rely on native "async" stacks that end up looking like this with source maps and ignore list enabled. <img width="673" alt="Screenshot 2024-05-22 at 4 00 27 PM" src="https://github.com/facebook/react/assets/63648/5313ed53-b298-4386-8f76-8eb85bdfbbc7"> Unfortunately Chrome requires a string name for each async stack and, worse, a suffix of `(async)` is automatically added which is very confusing since it seems like it might be an async component or something which it is not. In this case it's not so bad because it's nice to refer to the host component which otherwise doesn't have a stack frame since it's internal. However, if there were more owners here there would also be a `<Counter> (async)` which ends up being kind of duplicative. If the Chrome DevTools is not open from the start of the app, then `console.createTask` is disabled and so you lose the stack for those errors (or those parents if the devtools is opened later). Unlike our appended ones that are always added. That's unfortunate and likely to be a bit of a DX issue but it's also nice that it saves on perf in DEV mode for those cases. Framework dialogs can still surface the stack since we also track it in user space in parallel. This currently doesn't track Server Components yet. We need a more clever hack for that part in a follow up. I think I probably need to also add something to React DevTools to disable its stacks for this case too. Since it looks for stacks in the console.error and adds a stack otherwise. Since we don't add them anymore from the runtime, the DevTools adds them instead. DiffTrain build for commit ea6e059.
1 parent 15d1dee commit 50be937

File tree

7 files changed

+102
-75
lines changed

7 files changed

+102
-75
lines changed

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<1b15d797a9023201acc95022ba001e0f>>
10+
* @generated SignedSource<<5d2de112982cec5eac69c9d1f8e71fe5>>
1111
*/
1212

1313
'use strict';
@@ -22,6 +22,20 @@ var Scheduler$1 = require('scheduler');
2222

2323
var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
2424

25+
var debugRenderPhaseSideEffectsForStrictMode = false;
26+
var enableSchedulingProfiler = true;
27+
var enableProfilerTimer = true;
28+
var enableProfilerCommitHooks = true;
29+
var enableProfilerNestedUpdatePhase = true;
30+
var enableAsyncIterableChildren = false;
31+
var syncLaneExpirationMs = 250;
32+
var transitionLaneExpirationMs = 5000;
33+
var enableLazyContextPropagation = false;
34+
var enableLegacyHidden = false;
35+
var enableAsyncActions = true;
36+
var disableLegacyMode = false;
37+
var enableOwnerStacks = false; // Flow magic to verify the exports of this file match the original version.
38+
2539
// by calls to these methods by a Babel plugin.
2640
//
2741
// In PROD (or in packages without access to React internals),
@@ -48,7 +62,7 @@ function error(format) {
4862
printWarning('error', format, args);
4963
}
5064
}
51-
}
65+
} // eslint-disable-next-line react-internal/no-production-logging
5266

5367
function printWarning(level, format, args) {
5468
// When changing this logic, you might want to also
@@ -57,6 +71,9 @@ function printWarning(level, format, args) {
5771
var isErrorLogger = format === '%s\n\n%s\n' || format === '%o\n\n%s\n\n%s\n';
5872

5973
if (ReactSharedInternals.getCurrentStack) {
74+
// We only add the current stack to the console when createTask is not supported.
75+
// Since createTask requires DevTools to be open to work, this means that stacks
76+
// can be lost while DevTools isn't open but we can't detect this.
6077
var stack = ReactSharedInternals.getCurrentStack();
6178

6279
if (stack !== '') {
@@ -139,19 +156,6 @@ function set(key, value) {
139156
key._reactInternals = value;
140157
}
141158

142-
var debugRenderPhaseSideEffectsForStrictMode = false;
143-
var enableSchedulingProfiler = true;
144-
var enableProfilerTimer = true;
145-
var enableProfilerCommitHooks = true;
146-
var enableProfilerNestedUpdatePhase = true;
147-
var enableAsyncIterableChildren = false;
148-
var syncLaneExpirationMs = 250;
149-
var transitionLaneExpirationMs = 5000;
150-
var enableLazyContextPropagation = false;
151-
var enableLegacyHidden = false;
152-
var enableAsyncActions = true;
153-
var disableLegacyMode = false;
154-
155159
var FunctionComponent = 0;
156160
var ClassComponent = 1;
157161
var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
@@ -1058,6 +1062,8 @@ function runWithFiberInDEV(fiber, callback, arg0, arg1, arg2, arg3, arg4) {
10581062
setCurrentFiber(fiber);
10591063

10601064
try {
1065+
if (enableOwnerStacks) ;
1066+
10611067
return callback(arg0, arg1, arg2, arg3, arg4);
10621068
} finally {
10631069
current = previousFiber;
@@ -23456,7 +23462,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition
2345623462
return root;
2345723463
}
2345823464

23459-
var ReactVersion = '19.0.0-rc-aa7289e4';
23465+
var ReactVersion = '19.0.0-rc-44b67cc6';
2346023466

2346123467
/*
2346223468
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/JSXDEVRuntime-dev.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<498b38ab8fbbf44800642c8dc0009e44>>
10+
* @generated SignedSource<<d10d18b906d5290962ea3f530139aefd>>
1111
*/
1212

1313
'use strict';
@@ -82,7 +82,7 @@ function error(format) {
8282
printWarning('error', format, args);
8383
}
8484
}
85-
}
85+
} // eslint-disable-next-line react-internal/no-production-logging
8686

8787
function printWarning(level, format, args) {
8888
// When changing this logic, you might want to also
@@ -91,6 +91,9 @@ function printWarning(level, format, args) {
9191
var isErrorLogger = format === '%s\n\n%s\n' || format === '%o\n\n%s\n\n%s\n';
9292

9393
if (ReactSharedInternals.getCurrentStack) {
94+
// We only add the current stack to the console when createTask is not supported.
95+
// Since createTask requires DevTools to be open to work, this means that stacks
96+
// can be lost while DevTools isn't open but we can't detect this.
9497
var stack = ReactSharedInternals.getCurrentStack();
9598

9699
if (stack !== '') {

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/JSXRuntime-dev.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<0a367e8c426be018f37ef2a753bebe30>>
10+
* @generated SignedSource<<92915fe99444450e2d1431f2c1ba40f2>>
1111
*/
1212

1313
'use strict';
@@ -82,7 +82,7 @@ function error(format) {
8282
printWarning('error', format, args);
8383
}
8484
}
85-
}
85+
} // eslint-disable-next-line react-internal/no-production-logging
8686

8787
function printWarning(level, format, args) {
8888
// When changing this logic, you might want to also
@@ -91,6 +91,9 @@ function printWarning(level, format, args) {
9191
var isErrorLogger = format === '%s\n\n%s\n' || format === '%o\n\n%s\n\n%s\n';
9292

9393
if (ReactSharedInternals.getCurrentStack) {
94+
// We only add the current stack to the console when createTask is not supported.
95+
// Since createTask requires DevTools to be open to work, this means that stacks
96+
// can be lost while DevTools isn't open but we can't detect this.
9497
var stack = ReactSharedInternals.getCurrentStack();
9598

9699
if (stack !== '') {

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-dev.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<43472d2aa5457c3ff87b82ad5ff89a40>>
10+
* @generated SignedSource<<a504442f74a5c97d4fa7e8c91e8156f4>>
1111
*/
1212

1313
'use strict';
@@ -24,7 +24,7 @@ if (
2424
}
2525
var dynamicFlagsUntyped = require('ReactNativeInternalFeatureFlags');
2626

27-
var ReactVersion = '19.0.0-rc-28be327b';
27+
var ReactVersion = '19.0.0-rc-86d4e19f';
2828

2929
// Re-export dynamic flags from the internal module.
3030
var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on
@@ -125,7 +125,7 @@ function error(format) {
125125
printWarning('error', format, args);
126126
}
127127
}
128-
}
128+
} // eslint-disable-next-line react-internal/no-production-logging
129129

130130
function printWarning(level, format, args) {
131131
// When changing this logic, you might want to also
@@ -134,6 +134,9 @@ function printWarning(level, format, args) {
134134
var isErrorLogger = format === '%s\n\n%s\n' || format === '%o\n\n%s\n\n%s\n';
135135

136136
if (ReactSharedInternals.getCurrentStack) {
137+
// We only add the current stack to the console when createTask is not supported.
138+
// Since createTask requires DevTools to be open to work, this means that stacks
139+
// can be lost while DevTools isn't open but we can't detect this.
137140
var stack = ReactSharedInternals.getCurrentStack();
138141

139142
if (stack !== '') {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
b078c810c787cf13d9bd1958f083b4e3a162a720
1+
ea6e05912aa43a0bbfbee381752caa1817a41a86

compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<66f3250cfa263c3a4528924d68e4197c>>
10+
* @generated SignedSource<<d66dfe0f482a855f5a25c6611f697b38>>
1111
*/
1212

1313
'use strict';
@@ -30,6 +30,30 @@ var Scheduler = require('scheduler');
3030

3131
var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
3232

33+
// Re-export dynamic flags from the internal module.
34+
var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on
35+
// the exports object every time a flag is read.
36+
37+
var alwaysThrottleRetries = dynamicFlags.alwaysThrottleRetries,
38+
consoleManagedByDevToolsDuringStrictMode = dynamicFlags.consoleManagedByDevToolsDuringStrictMode,
39+
disableDefaultPropsExceptForClasses = dynamicFlags.disableDefaultPropsExceptForClasses,
40+
enableAddPropertiesFastPath = dynamicFlags.enableAddPropertiesFastPath,
41+
enableDeferRootSchedulingToMicrotask = dynamicFlags.enableDeferRootSchedulingToMicrotask,
42+
enableInfiniteRenderLoopDetection = dynamicFlags.enableInfiniteRenderLoopDetection,
43+
passChildrenWhenCloningPersistedNodes = dynamicFlags.passChildrenWhenCloningPersistedNodes; // The rest of the flags are static for better dead code elimination.
44+
var enableAsyncActions = true;
45+
var enableSchedulingProfiler = true;
46+
var enableProfilerTimer = true;
47+
var enableProfilerCommitHooks = true;
48+
var enableProfilerNestedUpdatePhase = true;
49+
var enableAsyncIterableChildren = false;
50+
var syncLaneExpirationMs = 250;
51+
var transitionLaneExpirationMs = 5000;
52+
var enableLazyContextPropagation = false;
53+
var enableLegacyHidden = false;
54+
var disableLegacyMode = false;
55+
var enableOwnerStacks = false; // Flow magic to verify the exports of this file match the original version.
56+
3357
var suppressWarning = false;
3458
function setSuppressWarning(newSuppressWarning) {
3559
{
@@ -62,7 +86,7 @@ function error(format) {
6286
printWarning('error', format, args);
6387
}
6488
}
65-
}
89+
} // eslint-disable-next-line react-internal/no-production-logging
6690

6791
function printWarning(level, format, args) {
6892
// When changing this logic, you might want to also
@@ -71,6 +95,9 @@ function printWarning(level, format, args) {
7195
var isErrorLogger = format === '%s\n\n%s\n' || format === '%o\n\n%s\n\n%s\n';
7296

7397
if (ReactSharedInternals.getCurrentStack) {
98+
// We only add the current stack to the console when createTask is not supported.
99+
// Since createTask requires DevTools to be open to work, this means that stacks
100+
// can be lost while DevTools isn't open but we can't detect this.
74101
var stack = ReactSharedInternals.getCurrentStack();
75102

76103
if (stack !== '') {
@@ -1998,29 +2025,6 @@ injectEventPluginsByName({
19982025
ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin
19992026
});
20002027

2001-
// Re-export dynamic flags from the internal module.
2002-
var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on
2003-
// the exports object every time a flag is read.
2004-
2005-
var alwaysThrottleRetries = dynamicFlags.alwaysThrottleRetries,
2006-
consoleManagedByDevToolsDuringStrictMode = dynamicFlags.consoleManagedByDevToolsDuringStrictMode,
2007-
disableDefaultPropsExceptForClasses = dynamicFlags.disableDefaultPropsExceptForClasses,
2008-
enableAddPropertiesFastPath = dynamicFlags.enableAddPropertiesFastPath,
2009-
enableDeferRootSchedulingToMicrotask = dynamicFlags.enableDeferRootSchedulingToMicrotask,
2010-
enableInfiniteRenderLoopDetection = dynamicFlags.enableInfiniteRenderLoopDetection,
2011-
passChildrenWhenCloningPersistedNodes = dynamicFlags.passChildrenWhenCloningPersistedNodes; // The rest of the flags are static for better dead code elimination.
2012-
var enableAsyncActions = true;
2013-
var enableSchedulingProfiler = true;
2014-
var enableProfilerTimer = true;
2015-
var enableProfilerCommitHooks = true;
2016-
var enableProfilerNestedUpdatePhase = true;
2017-
var enableAsyncIterableChildren = false;
2018-
var syncLaneExpirationMs = 250;
2019-
var transitionLaneExpirationMs = 5000;
2020-
var enableLazyContextPropagation = false;
2021-
var enableLegacyHidden = false;
2022-
var disableLegacyMode = false;
2023-
20242028
// Modules provided by RN:
20252029
var emptyObject$1 = {};
20262030
/**
@@ -5185,6 +5189,8 @@ function runWithFiberInDEV(fiber, callback, arg0, arg1, arg2, arg3, arg4) {
51855189
setCurrentFiber(fiber);
51865190

51875191
try {
5192+
if (enableOwnerStacks) ;
5193+
51885194
return callback(arg0, arg1, arg2, arg3, arg4);
51895195
} finally {
51905196
current = previousFiber;
@@ -26197,7 +26203,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition
2619726203
return root;
2619826204
}
2619926205

26200-
var ReactVersion = '19.0.0-rc-c70662b2';
26206+
var ReactVersion = '19.0.0-rc-571af8c1';
2620126207

2620226208
/*
2620326209
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol

compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<3d4cf8990ac0b10f2ad4552e0a0fc75f>>
10+
* @generated SignedSource<<3dbcb35ed104bc31d027dfdf6f5f8da0>>
1111
*/
1212

1313
'use strict';
@@ -30,6 +30,29 @@ var Scheduler = require('scheduler');
3030

3131
var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
3232

33+
// Re-export dynamic flags from the internal module.
34+
var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on
35+
// the exports object every time a flag is read.
36+
37+
var alwaysThrottleRetries = dynamicFlags.alwaysThrottleRetries,
38+
consoleManagedByDevToolsDuringStrictMode = dynamicFlags.consoleManagedByDevToolsDuringStrictMode,
39+
disableDefaultPropsExceptForClasses = dynamicFlags.disableDefaultPropsExceptForClasses,
40+
enableDeferRootSchedulingToMicrotask = dynamicFlags.enableDeferRootSchedulingToMicrotask,
41+
enableInfiniteRenderLoopDetection = dynamicFlags.enableInfiniteRenderLoopDetection;
42+
// The rest of the flags are static for better dead code elimination.
43+
var enableAsyncActions = true;
44+
var enableSchedulingProfiler = true;
45+
var enableProfilerTimer = true;
46+
var enableProfilerCommitHooks = true;
47+
var enableProfilerNestedUpdatePhase = true;
48+
var enableAsyncIterableChildren = false;
49+
var syncLaneExpirationMs = 250;
50+
var transitionLaneExpirationMs = 5000;
51+
var enableLazyContextPropagation = false;
52+
var enableLegacyHidden = false;
53+
var disableLegacyMode = false;
54+
var enableOwnerStacks = false; // Flow magic to verify the exports of this file match the original version.
55+
3356
var suppressWarning = false;
3457
function setSuppressWarning(newSuppressWarning) {
3558
{
@@ -62,7 +85,7 @@ function error(format) {
6285
printWarning('error', format, args);
6386
}
6487
}
65-
}
88+
} // eslint-disable-next-line react-internal/no-production-logging
6689

6790
function printWarning(level, format, args) {
6891
// When changing this logic, you might want to also
@@ -71,6 +94,9 @@ function printWarning(level, format, args) {
7194
var isErrorLogger = format === '%s\n\n%s\n' || format === '%o\n\n%s\n\n%s\n';
7295

7396
if (ReactSharedInternals.getCurrentStack) {
97+
// We only add the current stack to the console when createTask is not supported.
98+
// Since createTask requires DevTools to be open to work, this means that stacks
99+
// can be lost while DevTools isn't open but we can't detect this.
74100
var stack = ReactSharedInternals.getCurrentStack();
75101

76102
if (stack !== '') {
@@ -2346,28 +2372,6 @@ function set(key, value) {
23462372
key._reactInternals = value;
23472373
}
23482374

2349-
// Re-export dynamic flags from the internal module.
2350-
var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on
2351-
// the exports object every time a flag is read.
2352-
2353-
var alwaysThrottleRetries = dynamicFlags.alwaysThrottleRetries,
2354-
consoleManagedByDevToolsDuringStrictMode = dynamicFlags.consoleManagedByDevToolsDuringStrictMode,
2355-
disableDefaultPropsExceptForClasses = dynamicFlags.disableDefaultPropsExceptForClasses,
2356-
enableDeferRootSchedulingToMicrotask = dynamicFlags.enableDeferRootSchedulingToMicrotask,
2357-
enableInfiniteRenderLoopDetection = dynamicFlags.enableInfiniteRenderLoopDetection;
2358-
// The rest of the flags are static for better dead code elimination.
2359-
var enableAsyncActions = true;
2360-
var enableSchedulingProfiler = true;
2361-
var enableProfilerTimer = true;
2362-
var enableProfilerCommitHooks = true;
2363-
var enableProfilerNestedUpdatePhase = true;
2364-
var enableAsyncIterableChildren = false;
2365-
var syncLaneExpirationMs = 250;
2366-
var transitionLaneExpirationMs = 5000;
2367-
var enableLazyContextPropagation = false;
2368-
var enableLegacyHidden = false;
2369-
var disableLegacyMode = false;
2370-
23712375
// When adding new symbols to this file,
23722376
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
23732377
// The Symbol used to tag the ReactElement-like types.
@@ -3244,6 +3248,8 @@ function runWithFiberInDEV(fiber, callback, arg0, arg1, arg2, arg3, arg4) {
32443248
setCurrentFiber(fiber);
32453249

32463250
try {
3251+
if (enableOwnerStacks) ;
3252+
32473253
return callback(arg0, arg1, arg2, arg3, arg4);
32483254
} finally {
32493255
current = previousFiber;
@@ -26547,7 +26553,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition
2654726553
return root;
2654826554
}
2654926555

26550-
var ReactVersion = '19.0.0-rc-3589e53b';
26556+
var ReactVersion = '19.0.0-rc-7e1b1d14';
2655126557

2655226558
/*
2655326559
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol

0 commit comments

Comments
 (0)