@samitouri / QOS-React / commits / be94b10826

[Flight] Enable sync stack traces for errors and console replay (#31270)

This was gated behind `enableOwnerStacks` since they share some code paths but it's really part of `enableServerComponentLogs`. This just includes the server-side regular stack on Error/replayed logs but doesn't use console.createTask and doesn't include owner stacks.

Sebastian Markbåge committed Oct 16, 2024 at 10:57 UTC be94b108264e30873d4b679771e07ce14491e413
2 files changed +29 -7
packages/react-client/src/ReactFlightClient.js
+3 -4
@@ -46,6 +46,7 @@ import {
46 enableRefAsProp,
47 enableFlightReadableStream,
48 enableOwnerStacks,
49 + enableServerComponentLogs,
50 } from 'shared/ReactFeatureFlags';
51
52 import {
@@ -1928,7 +1929,7 @@ function resolveErrorDev(
1929 }
1930
1931 let error;
1931 - if (!enableOwnerStacks) {
1932 + if (!enableOwnerStacks && !enableServerComponentLogs) {
1933 // Executing Error within a native stack isn't really limited to owner stacks
1934 // but we gate it behind the same flag for now while iterating.
1935 // eslint-disable-next-line react-internal/prod-error-codes
@@ -2463,9 +2464,7 @@ function resolveConsoleEntry(
2464 const env = payload[3];
2465 const args = payload.slice(4);
2466
2466 - if (!enableOwnerStacks) {
2467 - // Printing with stack isn't really limited to owner stacks but
2468 - // we gate it behind the same flag for now while iterating.
2467 + if (!enableOwnerStacks && !enableServerComponentLogs) {
2468 bindToConsole(methodName, args, env)();
2469 return;
2470 }
packages/react-client/src/__tests__/ReactFlight-test.js
+26 -3
@@ -1346,7 +1346,10 @@ describe('ReactFlight', () => {
1346 errors: [
1347 {
1348 message: 'This is an error',
1349 - stack: gate(flags => flags.enableOwnerStacks)
1349 + stack: gate(
1350 + flags =>
1351 + flags.enableOwnerStacks || flags.enableServerComponentLogs,
1352 + )
1353 ? expect.stringContaining(
1354 'Error: This is an error\n' +
1355 ' at eval (eval at testFunction (eval at createFakeFunction (**), <anonymous>:1:35)\n' +
@@ -1378,7 +1381,17 @@ describe('ReactFlight', () => {
1381 ['file:///testing.js', 'Server'],
1382 [__filename, 'Server'],
1383 ]
1381 - : [],
1384 + : gate(flags => flags.enableServerComponentLogs)
1385 + ? [
1386 + // TODO: What should we request here? The outer (<anonymous>) or the inner (inspected-page.html)?
1387 + ['inspected-page.html:29:11), <anonymous>', 'Server'],
1388 + [
1389 + 'file://~/(some)(really)(exotic-directory)/ReactFlight-test.js',
1390 + 'Server',
1391 + ],
1392 + ['file:///testing.js', 'Server'],
1393 + ]
1394 + : [],
1395 });
1396 } else {
1397 expect(errors.map(getErrorForJestMatcher)).toEqual([
@@ -2940,7 +2953,11 @@ describe('ReactFlight', () => {
2953 .join('\n')
2954 .replaceAll(
2955 ' (/',
2943 - gate(flags => flags.enableOwnerStacks) ? ' (file:///' : ' (/',
2956 + gate(
2957 + flags => flags.enableOwnerStacks || flags.enableServerComponentLogs,
2958 + )
2959 + ? ' (file:///'
2960 + : ' (/',
2961 ); // The eval will end up normalizing these
2962
2963 let sawReactPrefix = false;
@@ -2974,6 +2991,12 @@ describe('ReactFlight', () => {
2991 'third-party',
2992 'third-party',
2993 ]);
2994 + } else if (__DEV__ && gate(flags => flags.enableServerComponentLogs)) {
2995 + expect(environments.slice(0, 3)).toEqual([
2996 + 'third-party',
2997 + 'third-party',
2998 + 'third-party',
2999 + ]);
3000 } else {
3001 expect(environments).toEqual([]);
3002 }