[Flight] Add react-stack-bottom-frame to console replaying (#30926)
Any time we're creating a stack trace we should have a react-stack-bottom-frame so we know what to filter out. This is the same thing we already do for createFakeJSXCallStackInDEV but we should do that when replaying logs too.
Sebastian Markbåge committed
Sep 9, 2024 at 19:52 UTC
49825c0ffc091f974e57bf6ed17c8d2eff5d5942
1 file changed
+69
-36
packages/react-client/src/ReactFlightClient.js
+69
-36
@@ -2332,6 +2332,61 @@ function getCurrentStackInDEV(): string {
2332
return '';
2333
}
2334
2335
+const replayConsoleWithCallStack = {
2336
+ 'react-stack-bottom-frame': function (
2337
+ response: Response,
2338
+ methodName: string,
2339
+ stackTrace: ReactStackTrace,
2340
+ owner: null | ReactComponentInfo,
2341
+ env: string,
2342
+ args: Array<mixed>,
2343
+ ): void {
2344
+ // There really shouldn't be anything else on the stack atm.
2345
+ const prevStack = ReactSharedInternals.getCurrentStack;
2346
+ ReactSharedInternals.getCurrentStack = getCurrentStackInDEV;
2347
+ currentOwnerInDEV = owner;
2348
+
2349
+ try {
2350
+ const callStack = buildFakeCallStack(
2351
+ response,
2352
+ stackTrace,
2353
+ env,
2354
+ bindToConsole(methodName, args, env),
2355
+ );
2356
+ if (owner != null) {
2357
+ const task = initializeFakeTask(response, owner, env);
2358
+ initializeFakeStack(response, owner);
2359
+ if (task !== null) {
2360
+ task.run(callStack);
2361
+ return;
2362
+ }
2363
+ }
2364
+ const rootTask = getRootTask(response, env);
2365
+ if (rootTask != null) {
2366
+ rootTask.run(callStack);
2367
+ return;
2368
+ }
2369
+ callStack();
2370
+ } finally {
2371
+ ReactSharedInternals.getCurrentStack = prevStack;
2372
+ }
2373
+ },
2374
+};
2375
+
2376
+const replayConsoleWithCallStackInDEV: (
2377
+ response: Response,
2378
+ methodName: string,
2379
+ stackTrace: ReactStackTrace,
2380
+ owner: null | ReactComponentInfo,
2381
+ env: string,
2382
+ args: Array<mixed>,
2383
+) => void = __DEV__
2384
+ ? // We use this technique to trick minifiers to preserve the function name.
2385
+ (replayConsoleWithCallStack['react-stack-bottom-frame'].bind(
2386
+ replayConsoleWithCallStack,
2387
+ ): any)
2388
+ : (null: any);
2389
+
2390
function resolveConsoleEntry(
2391
response: Response,
2392
value: UninitializedModel,
@@ -2361,43 +2416,21 @@ function resolveConsoleEntry(
2416
const env = payload[3];
2417
const args = payload.slice(4);
2418
2364
- // There really shouldn't be anything else on the stack atm.
2365
- const prevStack = ReactSharedInternals.getCurrentStack;
2366
- ReactSharedInternals.getCurrentStack = getCurrentStackInDEV;
2367
- currentOwnerInDEV = owner;
2368
-
2369
- try {
2370
- if (!enableOwnerStacks) {
2371
- // Printing with stack isn't really limited to owner stacks but
2372
- // we gate it behind the same flag for now while iterating.
2373
- bindToConsole(methodName, args, env)();
2374
- return;
2375
- }
2376
- const callStack = buildFakeCallStack(
2377
- response,
2378
- stackTrace,
2379
- env,
2380
- bindToConsole(methodName, args, env),
2381
- );
2382
- if (owner != null) {
2383
- const task = initializeFakeTask(response, owner, env);
2384
- initializeFakeStack(response, owner);
2385
- if (task !== null) {
2386
- task.run(callStack);
2387
- return;
2388
- }
2389
- // TODO: Set the current owner so that captureOwnerStack() adds the component
2390
- // stack during the replay - if needed.
2391
- }
2392
- const rootTask = getRootTask(response, env);
2393
- if (rootTask != null) {
2394
- rootTask.run(callStack);
2395
- return;
2396
- }
2397
- callStack();
2398
- } finally {
2399
- ReactSharedInternals.getCurrentStack = prevStack;
2419
+ if (!enableOwnerStacks) {
2420
+ // Printing with stack isn't really limited to owner stacks but
2421
+ // we gate it behind the same flag for now while iterating.
2422
+ bindToConsole(methodName, args, env)();
2423
+ return;
2424
}
2425
+
2426
+ replayConsoleWithCallStackInDEV(
2427
+ response,
2428
+ methodName,
2429
+ stackTrace,
2430
+ owner,
2431
+ env,
2432
+ args,
2433
+ );
2434
}
2435
2436
function mergeBuffer(