mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
[Flight] Log error if prod elements are rendered (#34189)
This commit is contained in:
parent
14c50e344c
commit
0032b2a3ee
|
|
@ -355,7 +355,7 @@ export function createLogAssertion(
|
|||
let argIndex = 0;
|
||||
// console.* could have been called with a non-string e.g. `console.error(new Error())`
|
||||
// eslint-disable-next-line react-internal/safe-string-coercion
|
||||
String(format).replace(/%s|%c/g, () => argIndex++);
|
||||
String(format).replace(/%s|%c|%o/g, () => argIndex++);
|
||||
if (argIndex !== args.length) {
|
||||
if (format.includes('%c%s')) {
|
||||
// We intentionally use mismatching formatting when printing badging because we don't know
|
||||
|
|
|
|||
21
packages/react-server/src/ReactFlightServer.js
vendored
21
packages/react-server/src/ReactFlightServer.js
vendored
|
|
@ -3354,6 +3354,27 @@ function renderModelDestructive(
|
|||
task.debugOwner = element._owner;
|
||||
task.debugStack = element._debugStack;
|
||||
task.debugTask = element._debugTask;
|
||||
if (
|
||||
element._owner === undefined ||
|
||||
element._debugStack === undefined ||
|
||||
element._debugTask === undefined
|
||||
) {
|
||||
let key = '';
|
||||
if (element.key !== null) {
|
||||
key = ' key="' + element.key + '"';
|
||||
}
|
||||
|
||||
console.error(
|
||||
'Attempted to render <%s%s> without development properties. ' +
|
||||
'This is not supported. It can happen if:' +
|
||||
'\n- The element is created with a production version of React but rendered in development.' +
|
||||
'\n- The element was cloned with a custom function instead of `React.cloneElement`.\n' +
|
||||
'The props of this element may help locate this element: %o',
|
||||
element.type,
|
||||
key,
|
||||
element.props,
|
||||
);
|
||||
}
|
||||
// TODO: Pop this. Since we currently don't have a point where we can pop the stack
|
||||
// this debug information will be used for errors inside sibling properties that
|
||||
// are not elements. Leading to the wrong attribution on the server. We could fix
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ let ReactNoopFlightServer;
|
|||
let Scheduler;
|
||||
let advanceTimersByTime;
|
||||
let assertLog;
|
||||
let assertConsoleErrorDev;
|
||||
|
||||
describe('ReactFlight', () => {
|
||||
beforeEach(() => {
|
||||
|
|
@ -64,6 +65,7 @@ describe('ReactFlight', () => {
|
|||
Scheduler = require('scheduler');
|
||||
const InternalTestUtils = require('internal-test-utils');
|
||||
assertLog = InternalTestUtils.assertLog;
|
||||
assertConsoleErrorDev = InternalTestUtils.assertConsoleErrorDev;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
|
@ -175,4 +177,26 @@ describe('ReactFlight', () => {
|
|||
stackTwo: '\n in OwnerStackDelayed (at **)' + '\n in App (at **)',
|
||||
});
|
||||
});
|
||||
|
||||
it('logs an error when prod elements are rendered', async () => {
|
||||
const element = ReactServer.createElement('span', {
|
||||
key: 'one',
|
||||
children: 'Free!',
|
||||
});
|
||||
ReactNoopFlightServer.render(
|
||||
// bad clone
|
||||
{...element},
|
||||
);
|
||||
|
||||
assertConsoleErrorDev([
|
||||
[
|
||||
'Attempted to render <span key="one"> without development properties. This is not supported. It can happen if:' +
|
||||
'\n- The element is created with a production version of React but rendered in development.' +
|
||||
'\n- The element was cloned with a custom function instead of `React.cloneElement`.\n' +
|
||||
"The props of this element may help locate this element: { children: 'Free!', [key]: [Getter] }",
|
||||
{withoutStack: true},
|
||||
],
|
||||
"TypeError: Cannot read properties of undefined (reading 'stack')",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user