mirror of
https://github.com/facebook/react.git
synced 2026-02-26 05:55:02 +00:00
This information is available in the regular stack but since that's hidden behind an expando and our appended stack to logs is not hidden, it hides the most important frames like the name of the current component. This is closer to what happens to the native stack. We only include stacks if they're within a ReactFiberCallUserSpace call frame. This should be most that have a current fiber but this is critical to filtering out most React frames if the regular node_modules filter doesn't work. Most React warnings fire during the rendering phase and not inside a user space function but some do like hooks warnings and setState in render. This feature is more important if we port this to React DevTools appending stacks to all logs where it's likely to originate from inside a component and you want the line within that component to immediately part of the visible stack. One thing that kind sucks is that we don't have a reliable way to exclude React internal stack frames. We filter node_modules but it might not match. For other cases I try hard to only track the stack frame at the root of React (e.g. immediately inside createElement) until the ReactFiberCallUserSpace so we don't need the filtering to work. In this case it's hard to achieve the same thing though. This is easier in RDT because we have the start/end line and parsing of stack traces so we can use that to exclude internals but that's a lot of code/complexity for shipping within the library. For example in Safari: <img width="590" alt="Screenshot 2024-05-31 at 6 15 27 PM" src="https://github.com/facebook/react/assets/63648/2820c8c0-8a03-42e9-8678-8348f66b051a"> Ideally warnOnUseFormStateInDev and useFormState wouldn't be included since they're React internals. Before this change, the Counter.js line also wasn't included though which points to exactly where the error is within the user code. (Note Server Components have V8 formatted lines and Client Components have JSC formatted lines.)
53 lines
1.4 KiB
JavaScript
53 lines
1.4 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.
|
|
*/
|
|
|
|
// This refers to a WWW module.
|
|
const warningWWW = require('warning');
|
|
|
|
let suppressWarning = false;
|
|
export function setSuppressWarning(newSuppressWarning) {
|
|
if (__DEV__) {
|
|
suppressWarning = newSuppressWarning;
|
|
}
|
|
}
|
|
|
|
export function warn(format, ...args) {
|
|
if (__DEV__) {
|
|
if (!suppressWarning) {
|
|
printWarning('warn', format, args, new Error('react-stack-top-frame'));
|
|
}
|
|
}
|
|
}
|
|
|
|
export function error(format, ...args) {
|
|
if (__DEV__) {
|
|
if (!suppressWarning) {
|
|
printWarning('error', format, args, new Error('react-stack-top-frame'));
|
|
}
|
|
}
|
|
}
|
|
|
|
function printWarning(level, format, args, currentStack) {
|
|
if (__DEV__) {
|
|
const React = require('react');
|
|
const ReactSharedInternals =
|
|
React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
|
|
// Defensive in case this is fired before React is initialized.
|
|
if (ReactSharedInternals != null && ReactSharedInternals.getCurrentStack) {
|
|
const stack = ReactSharedInternals.getCurrentStack(currentStack);
|
|
if (stack !== '') {
|
|
format += '%s';
|
|
args.push(stack);
|
|
}
|
|
}
|
|
// TODO: don't ignore level and pass it down somewhere too.
|
|
args.unshift(format);
|
|
args.unshift(false);
|
|
warningWWW.apply(null, args);
|
|
}
|
|
}
|