react/packages/shared/ReactOwnerStackFrames.js
Ruslan Lesiutin 91d097b2c5
fix: rename bottom stack frame (#33680)
`react-stack-bottom-frame` -> `react_stack_bottom_frame`.

This survives `@babel/plugin-transform-function-name`, but now frames
will be displayed as `at Object.react_stack_bottom_frame (...)` in V8.
Checks that were relying on exact function name match were updated to
use either `.indexOf()` or `.includes()`

For backwards compatibility, both React DevTools and Flight Client will
look for both options. I am not so sure about the latter and if React
version is locked.
2025-07-01 18:06:26 +01:00

42 lines
1.3 KiB
JavaScript

/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import DefaultPrepareStackTrace from 'shared/DefaultPrepareStackTrace';
export function formatOwnerStack(error: Error): string {
const prevPrepareStackTrace = Error.prepareStackTrace;
Error.prepareStackTrace = DefaultPrepareStackTrace;
let stack = error.stack;
Error.prepareStackTrace = prevPrepareStackTrace;
if (stack.startsWith('Error: react-stack-top-frame\n')) {
// V8's default formatting prefixes with the error message which we
// don't want/need.
stack = stack.slice(29);
}
let idx = stack.indexOf('\n');
if (idx !== -1) {
// Pop the JSX frame.
stack = stack.slice(idx + 1);
}
idx = stack.indexOf('react_stack_bottom_frame');
if (idx !== -1) {
idx = stack.lastIndexOf('\n', idx);
}
if (idx !== -1) {
// Cut off everything after the bottom frame since it'll be internals.
stack = stack.slice(0, idx);
} else {
// We didn't find any internal callsite out to user space.
// This means that this was called outside an owner or the owner is fully internal.
// To keep things light we exclude the entire trace in this case.
return '';
}
return stack;
}