Skip to content

Commit 2774208

Browse files
authored
Remove Warning: prefix and toString on console Arguments (facebook#29839)
Basically make `console.error` and `console.warn` behave like normal - when a component stack isn't appended. I need this because I need to be able to print rich logs with the component stack option and to be able to disable instrumentation completely in `console.createTask` environments that don't need it. Currently we can't print logs with richer objects because they're toString:ed first. In practice, pretty much all arguments we log are already toString:ed so it's not necessary anyway. Some might be like a number. So it would only be a problem if some environment can't handle proper consoles but then it's up to that environment to toString it before logging. The `Warning: ` prefix is historic and is both noisy and confusing. It's mostly unnecessary since the UI surrounding `console.error` and `console.warn` tend to have visual treatment around it anyway. However, it's actively misleading when `console.error` gets prefixed with a Warning that we consider an error level. There's an argument to be made that some of our `console.error` don't make the bar for an error but then the argument is to downgrade each of those to `console.warn` - not to brand all our actual error logging with `Warning: `. Apparently something needs to change in React Native before landing this because it depends on the prefix somehow which probably doesn't make sense already.
1 parent d172bda commit 2774208

File tree

77 files changed

+397
-418
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+397
-418
lines changed

packages/internal-test-utils/shouldIgnoreConsoleError.js

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ module.exports = function shouldIgnoreConsoleError(format, args) {
77
args[0] != null &&
88
((typeof args[0] === 'object' &&
99
typeof args[0].message === 'string' &&
10+
// This specific log has the same signature as error logging.
11+
// The trick is to get rid of this whole file.
12+
!format.includes('Failed to serialize an action') &&
1013
typeof args[0].stack === 'string') ||
1114
(typeof args[0] === 'string' &&
1215
args[0].indexOf('An error occurred in ') === 0))

packages/react-cache/src/__tests__/ReactCacheOld-test.internal.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ describe('ReactCache', () => {
182182
await waitForAll(['App', 'Loading...']);
183183
}).toErrorDev([
184184
'Invalid key type. Expected a string, number, symbol, or ' +
185-
'boolean, but instead received: Hi,100\n\n' +
185+
"boolean, but instead received: [ 'Hi', 100 ]\n\n" +
186186
'To use non-primitive values as keys, you must pass a hash ' +
187187
'function as the second argument to createResource().',
188188
]);

packages/react-devtools-shared/src/__tests__/inspectedElement-test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2556,7 +2556,7 @@ describe('InspectedElement', () => {
25562556
};
25572557

25582558
await withErrorsOrWarningsIgnored(
2559-
['Warning: Each child in a list should have a unique "key" prop.'],
2559+
['Each child in a list should have a unique "key" prop.'],
25602560
async () => {
25612561
await utils.actAsync(() =>
25622562
render(<Example repeatWarningCount={1} />),

packages/react-devtools-shared/src/__tests__/setupTests.js

+10-11
Original file line numberDiff line numberDiff line change
@@ -154,23 +154,22 @@ beforeEach(() => {
154154

155155
const originalConsoleError = console.error;
156156
console.error = (...args) => {
157-
const firstArg = args[0];
158-
if (
159-
firstArg === 'Warning: React instrumentation encountered an error: %s'
160-
) {
157+
let firstArg = args[0];
158+
if (typeof firstArg === 'string' && firstArg.startsWith('Warning: ')) {
159+
// Older React versions might use the Warning: prefix. I'm not sure
160+
// if they use this code path.
161+
firstArg = firstArg.slice(9);
162+
}
163+
if (firstArg === 'React instrumentation encountered an error: %s') {
161164
// Rethrow errors from React.
162165
throw args[1];
163166
} else if (
164167
typeof firstArg === 'string' &&
165-
(firstArg.startsWith(
166-
"Warning: It looks like you're using the wrong act()",
167-
) ||
168+
(firstArg.startsWith("It looks like you're using the wrong act()") ||
168169
firstArg.startsWith(
169-
'Warning: The current testing environment is not configured to support act',
170+
'The current testing environment is not configured to support act',
170171
) ||
171-
firstArg.startsWith(
172-
'Warning: You seem to have overlapping act() calls',
173-
))
172+
firstArg.startsWith('You seem to have overlapping act() calls'))
174173
) {
175174
// DevTools intentionally wraps updates with acts from both DOM and test-renderer,
176175
// since test updates are expected to impact both renderers.

packages/react-devtools-shared/src/__tests__/store-test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1927,7 +1927,7 @@ describe('Store', () => {
19271927
}
19281928

19291929
withErrorsOrWarningsIgnored(
1930-
['Warning: Each child in a list should have a unique "key" prop'],
1930+
['Each child in a list should have a unique "key" prop'],
19311931
() => {
19321932
act(() => render(<Example />));
19331933
},
@@ -1952,7 +1952,7 @@ describe('Store', () => {
19521952
}
19531953

19541954
withErrorsOrWarningsIgnored(
1955-
['Warning: Each child in a list should have a unique "key" prop'],
1955+
['Each child in a list should have a unique "key" prop'],
19561956
() => {
19571957
act(() => render(<Example />));
19581958
},

packages/react-devtools-shell/src/app/index.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,18 @@ ignoreErrors([
3232
'Warning: %s is deprecated in StrictMode.', // findDOMNode
3333
'Warning: ReactDOM.render was removed in React 19',
3434
'Warning: react-test-renderer is deprecated',
35+
// Ignore prefixed and not prefixed since I don't know which
36+
// React versions are being tested by this code.
37+
'Legacy context API',
38+
'Unsafe lifecycle methods',
39+
'%s is deprecated in StrictMode.', // findDOMNode
40+
'ReactDOM.render was removed in React 19',
41+
'react-test-renderer is deprecated',
42+
]);
43+
ignoreWarnings([
44+
'Warning: componentWillReceiveProps has been renamed',
45+
'componentWillReceiveProps has been renamed',
3546
]);
36-
ignoreWarnings(['Warning: componentWillReceiveProps has been renamed']);
3747
ignoreLogs([]);
3848

3949
const unmountFunctions: Array<() => void | boolean> = [];

packages/react-dom-bindings/src/client/validateDOMNesting.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ function validateDOMNesting(
484484
// TODO: Format this as a linkified "diff view" with props instead of
485485
// a stack trace since the stack trace format is now for owner stacks.
486486
console['error'](
487-
'Warning: In HTML, %s cannot be a child of <%s>.%s\n' +
487+
'In HTML, %s cannot be a child of <%s>.%s\n' +
488488
'This will cause a hydration error.%s',
489489
tagDisplayName,
490490
ancestorTag,
@@ -498,7 +498,7 @@ function validateDOMNesting(
498498
// TODO: Format this as a linkified "diff view" with props instead of
499499
// a stack trace since the stack trace format is now for owner stacks.
500500
console['error'](
501-
'Warning: In HTML, %s cannot be a descendant of <%s>.\n' +
501+
'In HTML, %s cannot be a descendant of <%s>.\n' +
502502
'This will cause a hydration error.%s',
503503
tagDisplayName,
504504
ancestorTag,
@@ -530,7 +530,7 @@ function validateTextNesting(childText: string, parentTag: string): boolean {
530530
// TODO: Format this as a linkified "diff view" with props instead of
531531
// a stack trace since the stack trace format is now for owner stacks.
532532
console['error'](
533-
'Warning: In HTML, text nodes cannot be a child of <%s>.\n' +
533+
'In HTML, text nodes cannot be a child of <%s>.\n' +
534534
'This will cause a hydration error.%s',
535535
parentTag,
536536
getCurrentParentStackInDev(),
@@ -542,7 +542,7 @@ function validateTextNesting(childText: string, parentTag: string): boolean {
542542
// TODO: Format this as a linkified "diff view" with props instead of
543543
// a stack trace since the stack trace format is now for owner stacks.
544544
console['error'](
545-
'Warning: In HTML, whitespace text nodes cannot be a child of <%s>. ' +
545+
'In HTML, whitespace text nodes cannot be a child of <%s>. ' +
546546
"Make sure you don't have any extra whitespace between tags on " +
547547
'each line of your source code.\n' +
548548
'This will cause a hydration error.%s',

packages/react-dom/src/__tests__/CSSPropertyOperations-test.js

+9-9
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ describe('CSSPropertyOperations', () => {
108108
root.render(<Comp />);
109109
});
110110
}).toErrorDev(
111-
'Warning: Unsupported style property background-color. Did you mean backgroundColor?' +
111+
'Unsupported style property background-color. Did you mean backgroundColor?' +
112112
'\n in div (at **)' +
113113
'\n in Comp (at **)',
114114
);
@@ -137,10 +137,10 @@ describe('CSSPropertyOperations', () => {
137137
root.render(<Comp style={styles} />);
138138
});
139139
}).toErrorDev([
140-
'Warning: Unsupported style property -ms-transform. Did you mean msTransform?' +
140+
'Unsupported style property -ms-transform. Did you mean msTransform?' +
141141
'\n in div (at **)' +
142142
'\n in Comp (at **)',
143-
'Warning: Unsupported style property -webkit-transform. Did you mean WebkitTransform?' +
143+
'Unsupported style property -webkit-transform. Did you mean WebkitTransform?' +
144144
'\n in div (at **)' +
145145
'\n in Comp (at **)',
146146
]);
@@ -171,11 +171,11 @@ describe('CSSPropertyOperations', () => {
171171
});
172172
}).toErrorDev([
173173
// msTransform is correct already and shouldn't warn
174-
'Warning: Unsupported vendor-prefixed style property oTransform. ' +
174+
'Unsupported vendor-prefixed style property oTransform. ' +
175175
'Did you mean OTransform?' +
176176
'\n in div (at **)' +
177177
'\n in Comp (at **)',
178-
'Warning: Unsupported vendor-prefixed style property webkitTransform. ' +
178+
'Unsupported vendor-prefixed style property webkitTransform. ' +
179179
'Did you mean WebkitTransform?' +
180180
'\n in div (at **)' +
181181
'\n in Comp (at **)',
@@ -207,11 +207,11 @@ describe('CSSPropertyOperations', () => {
207207
root.render(<Comp />);
208208
});
209209
}).toErrorDev([
210-
"Warning: Style property values shouldn't contain a semicolon. " +
210+
"Style property values shouldn't contain a semicolon. " +
211211
'Try "backgroundColor: blue" instead.' +
212212
'\n in div (at **)' +
213213
'\n in Comp (at **)',
214-
"Warning: Style property values shouldn't contain a semicolon. " +
214+
"Style property values shouldn't contain a semicolon. " +
215215
'Try "color: red" instead.' +
216216
'\n in div (at **)' +
217217
'\n in Comp (at **)',
@@ -234,7 +234,7 @@ describe('CSSPropertyOperations', () => {
234234
root.render(<Comp />);
235235
});
236236
}).toErrorDev(
237-
'Warning: `NaN` is an invalid value for the `fontSize` css style property.' +
237+
'`NaN` is an invalid value for the `fontSize` css style property.' +
238238
'\n in div (at **)' +
239239
'\n in Comp (at **)',
240240
);
@@ -270,7 +270,7 @@ describe('CSSPropertyOperations', () => {
270270
root.render(<Comp />);
271271
});
272272
}).toErrorDev(
273-
'Warning: `Infinity` is an invalid value for the `fontSize` css style property.' +
273+
'`Infinity` is an invalid value for the `fontSize` css style property.' +
274274
'\n in div (at **)' +
275275
'\n in Comp (at **)',
276276
);

packages/react-dom/src/__tests__/DOMPropertyOperations-test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1333,7 +1333,7 @@ describe('DOMPropertyOperations', () => {
13331333
});
13341334

13351335
assertConsoleErrorDev([
1336-
'The `popoverTarget` prop expects the ID of an Element as a string. Received [object HTMLDivElement] instead.',
1336+
'The `popoverTarget` prop expects the ID of an Element as a string. Received HTMLDivElement {} instead.',
13371337
]);
13381338

13391339
// Dedupe warning

packages/react-dom/src/__tests__/ReactComponent-test.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ describe('ReactComponent', () => {
217217
root.render(<Component />);
218218
});
219219
}).toErrorDev([
220-
'Warning: Component "Component" contains the string ref "inner". ' +
220+
'Component "Component" contains the string ref "inner". ' +
221221
'Support for string refs will be removed in a future major release. ' +
222222
'We recommend using useRef() or createRef() instead. ' +
223223
'Learn more about using refs safely here: https://react.dev/link/strict-mode-string-ref\n' +
@@ -711,7 +711,7 @@ describe('ReactComponent', () => {
711711
root.render(<Foo />);
712712
});
713713
}).toErrorDev(
714-
'Warning: Functions are not valid as a React child. This may happen if ' +
714+
'Functions are not valid as a React child. This may happen if ' +
715715
'you return Foo instead of <Foo /> from render. ' +
716716
'Or maybe you meant to call this function rather than return it.\n' +
717717
' <Foo>{Foo}</Foo>\n' +
@@ -733,7 +733,7 @@ describe('ReactComponent', () => {
733733
root.render(<Foo />);
734734
});
735735
}).toErrorDev(
736-
'Warning: Functions are not valid as a React child. This may happen if ' +
736+
'Functions are not valid as a React child. This may happen if ' +
737737
'you return Foo instead of <Foo /> from render. ' +
738738
'Or maybe you meant to call this function rather than return it.\n' +
739739
' <Foo>{Foo}</Foo>\n' +
@@ -756,7 +756,7 @@ describe('ReactComponent', () => {
756756
root.render(<Foo />);
757757
});
758758
}).toErrorDev(
759-
'Warning: Functions are not valid as a React child. This may happen if ' +
759+
'Functions are not valid as a React child. This may happen if ' +
760760
'you return Foo instead of <Foo /> from render. ' +
761761
'Or maybe you meant to call this function rather than return it.\n' +
762762
' <span>{Foo}</span>\n' +
@@ -811,13 +811,13 @@ describe('ReactComponent', () => {
811811
root.render(<Foo ref={current => (component = current)} />);
812812
});
813813
}).toErrorDev([
814-
'Warning: Functions are not valid as a React child. This may happen if ' +
814+
'Functions are not valid as a React child. This may happen if ' +
815815
'you return Foo instead of <Foo /> from render. ' +
816816
'Or maybe you meant to call this function rather than return it.\n' +
817817
' <div>{Foo}</div>\n' +
818818
' in div (at **)\n' +
819819
' in Foo (at **)',
820-
'Warning: Functions are not valid as a React child. This may happen if ' +
820+
'Functions are not valid as a React child. This may happen if ' +
821821
'you return Foo instead of <Foo /> from render. ' +
822822
'Or maybe you meant to call this function rather than return it.\n' +
823823
' <span>{Foo}</span>\n' +

packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ describe('ReactComponentLifeCycle', () => {
271271
root.render(<StatefulComponent />);
272272
});
273273
}).toErrorDev(
274-
"Warning: Can't call setState on a component that is not yet mounted. " +
274+
"Can't call setState on a component that is not yet mounted. " +
275275
'This is a no-op, but it might indicate a bug in your application. ' +
276276
'Instead, assign to `this.state` directly or define a `state = {};` ' +
277277
'class property with the desired state in the StatefulComponent component.',
@@ -1504,20 +1504,20 @@ describe('ReactComponentLifeCycle', () => {
15041504
}).toWarnDev(
15051505
[
15061506
/* eslint-disable max-len */
1507-
`Warning: componentWillMount has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
1507+
`componentWillMount has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
15081508
15091509
* Move code with side effects to componentDidMount, and set initial state in the constructor.
15101510
* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder.
15111511
15121512
Please update the following components: MyComponent`,
1513-
`Warning: componentWillReceiveProps has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
1513+
`componentWillReceiveProps has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
15141514
15151515
* Move data fetching code or side effects to componentDidUpdate.
15161516
* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state
15171517
* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder.
15181518
15191519
Please update the following components: MyComponent`,
1520-
`Warning: componentWillUpdate has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
1520+
`componentWillUpdate has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
15211521
15221522
* Move data fetching code or side effects to componentDidUpdate.
15231523
* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder.

packages/react-dom/src/__tests__/ReactCompositeComponent-test.js

+11-11
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ describe('ReactCompositeComponent', () => {
313313
root.render(<MyComponent />);
314314
});
315315
}).toErrorDev(
316-
"Warning: Can't call forceUpdate on a component that is not yet mounted. " +
316+
"Can't call forceUpdate on a component that is not yet mounted. " +
317317
'This is a no-op, but it might indicate a bug in your application. ' +
318318
'Instead, assign to `this.state` directly or define a `state = {};` ' +
319319
'class property with the desired state in the MyComponent component.',
@@ -347,7 +347,7 @@ describe('ReactCompositeComponent', () => {
347347
root.render(<MyComponent />);
348348
});
349349
}).toErrorDev(
350-
"Warning: Can't call setState on a component that is not yet mounted. " +
350+
"Can't call setState on a component that is not yet mounted. " +
351351
'This is a no-op, but it might indicate a bug in your application. ' +
352352
'Instead, assign to `this.state` directly or define a `state = {};` ' +
353353
'class property with the desired state in the MyComponent component.',
@@ -484,7 +484,7 @@ describe('ReactCompositeComponent', () => {
484484
});
485485
}).rejects.toThrow(TypeError);
486486
}).toErrorDev(
487-
'Warning: The <ClassWithRenderNotExtended /> component appears to have a render method, ' +
487+
'The <ClassWithRenderNotExtended /> component appears to have a render method, ' +
488488
"but doesn't extend React.Component. This is likely to cause errors. " +
489489
'Change ClassWithRenderNotExtended to extend React.Component instead.',
490490
);
@@ -631,7 +631,7 @@ describe('ReactCompositeComponent', () => {
631631
instance.setState({bogus: true});
632632
});
633633
}).toErrorDev(
634-
'Warning: ClassComponent.shouldComponentUpdate(): Returned undefined instead of a ' +
634+
'ClassComponent.shouldComponentUpdate(): Returned undefined instead of a ' +
635635
'boolean value. Make sure to return true or false.',
636636
);
637637
});
@@ -651,7 +651,7 @@ describe('ReactCompositeComponent', () => {
651651
root.render(<Component />);
652652
});
653653
}).toErrorDev(
654-
'Warning: Component has a method called ' +
654+
'Component has a method called ' +
655655
'componentDidUnmount(). But there is no such lifecycle method. ' +
656656
'Did you mean componentWillUnmount()?',
657657
);
@@ -673,7 +673,7 @@ describe('ReactCompositeComponent', () => {
673673
root.render(<Component />);
674674
});
675675
}).toErrorDev(
676-
'Warning: Component has a method called ' +
676+
'Component has a method called ' +
677677
'componentDidReceiveProps(). But there is no such lifecycle method. ' +
678678
'If you meant to update the state in response to changing props, ' +
679679
'use componentWillReceiveProps(). If you meant to fetch data or ' +
@@ -699,7 +699,7 @@ describe('ReactCompositeComponent', () => {
699699
root.render(<Component />);
700700
});
701701
}).toErrorDev(
702-
'Warning: Setting defaultProps as an instance property on Component is not supported ' +
702+
'Setting defaultProps as an instance property on Component is not supported ' +
703703
'and will be ignored. Instead, define defaultProps as a static property on Component.',
704704
);
705705
});
@@ -1199,9 +1199,9 @@ describe('ReactCompositeComponent', () => {
11991199
});
12001200
}).rejects.toThrow();
12011201
}).toErrorDev([
1202-
'Warning: No `render` method found on the RenderTextInvalidConstructor instance: ' +
1202+
'No `render` method found on the RenderTextInvalidConstructor instance: ' +
12031203
'did you accidentally return an object from the constructor?',
1204-
'Warning: No `render` method found on the RenderTextInvalidConstructor instance: ' +
1204+
'No `render` method found on the RenderTextInvalidConstructor instance: ' +
12051205
'did you accidentally return an object from the constructor?',
12061206
]);
12071207
});
@@ -1239,9 +1239,9 @@ describe('ReactCompositeComponent', () => {
12391239
});
12401240
}).rejects.toThrow();
12411241
}).toErrorDev([
1242-
'Warning: No `render` method found on the RenderTestUndefinedRender instance: ' +
1242+
'No `render` method found on the RenderTestUndefinedRender instance: ' +
12431243
'you may have forgotten to define `render`.',
1244-
'Warning: No `render` method found on the RenderTestUndefinedRender instance: ' +
1244+
'No `render` method found on the RenderTestUndefinedRender instance: ' +
12451245
'you may have forgotten to define `render`.',
12461246
]);
12471247
});

0 commit comments

Comments
 (0)