From da8de9e51458f87fd4b0cf91b6f89b8bd0d06ab1 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Tue, 15 Oct 2024 17:16:25 -0400 Subject: [PATCH] Enable sync stack traces for errors and console replay --- .../react-client/src/ReactFlightClient.js | 7 ++--- .../src/__tests__/ReactFlight-test.js | 29 +++++++++++++++++-- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/packages/react-client/src/ReactFlightClient.js b/packages/react-client/src/ReactFlightClient.js index 141058fb9dfb2..2a6165c932a16 100644 --- a/packages/react-client/src/ReactFlightClient.js +++ b/packages/react-client/src/ReactFlightClient.js @@ -46,6 +46,7 @@ import { enableRefAsProp, enableFlightReadableStream, enableOwnerStacks, + enableServerComponentLogs, } from 'shared/ReactFeatureFlags'; import { @@ -1928,7 +1929,7 @@ function resolveErrorDev( } let error; - if (!enableOwnerStacks) { + if (!enableOwnerStacks && !enableServerComponentLogs) { // Executing Error within a native stack isn't really limited to owner stacks // but we gate it behind the same flag for now while iterating. // eslint-disable-next-line react-internal/prod-error-codes @@ -2463,9 +2464,7 @@ function resolveConsoleEntry( const env = payload[3]; const args = payload.slice(4); - if (!enableOwnerStacks) { - // Printing with stack isn't really limited to owner stacks but - // we gate it behind the same flag for now while iterating. + if (!enableOwnerStacks && !enableServerComponentLogs) { bindToConsole(methodName, args, env)(); return; } diff --git a/packages/react-client/src/__tests__/ReactFlight-test.js b/packages/react-client/src/__tests__/ReactFlight-test.js index 7e1017276c976..92efd84bf0d7a 100644 --- a/packages/react-client/src/__tests__/ReactFlight-test.js +++ b/packages/react-client/src/__tests__/ReactFlight-test.js @@ -1346,7 +1346,10 @@ describe('ReactFlight', () => { errors: [ { message: 'This is an error', - stack: gate(flags => flags.enableOwnerStacks) + stack: gate( + flags => + flags.enableOwnerStacks || flags.enableServerComponentLogs, + ) ? expect.stringContaining( 'Error: This is an error\n' + ' at eval (eval at testFunction (eval at createFakeFunction (**), :1:35)\n' + @@ -1378,7 +1381,17 @@ describe('ReactFlight', () => { ['file:///testing.js', 'Server'], [__filename, 'Server'], ] - : [], + : gate(flags => flags.enableServerComponentLogs) + ? [ + // TODO: What should we request here? The outer () or the inner (inspected-page.html)? + ['inspected-page.html:29:11), ', 'Server'], + [ + 'file://~/(some)(really)(exotic-directory)/ReactFlight-test.js', + 'Server', + ], + ['file:///testing.js', 'Server'], + ] + : [], }); } else { expect(errors.map(getErrorForJestMatcher)).toEqual([ @@ -2940,7 +2953,11 @@ describe('ReactFlight', () => { .join('\n') .replaceAll( ' (/', - gate(flags => flags.enableOwnerStacks) ? ' (file:///' : ' (/', + gate( + flags => flags.enableOwnerStacks || flags.enableServerComponentLogs, + ) + ? ' (file:///' + : ' (/', ); // The eval will end up normalizing these let sawReactPrefix = false; @@ -2974,6 +2991,12 @@ describe('ReactFlight', () => { 'third-party', 'third-party', ]); + } else if (__DEV__ && gate(flags => flags.enableServerComponentLogs)) { + expect(environments.slice(0, 3)).toEqual([ + 'third-party', + 'third-party', + 'third-party', + ]); } else { expect(environments).toEqual([]); }