Skip to content
3 changes: 2 additions & 1 deletion packages/react-dom/src/client/ReactDOMFiberInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,8 @@ function updateNamedCousins(rootNode, props) {
invariant(
otherProps,
'ReactDOMInput: Mixing React and non-React radio inputs with the ' +
'same `name` is not supported.',
'same `name` is not supported.%s',
getCurrentFiberStackAddendum() || '',
);

// We need update the tracked value on the named cousin since the value
Expand Down
3 changes: 2 additions & 1 deletion packages/react-dom/src/client/ReactDOMFiberTextarea.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ export function getHostProps(element: Element, props: Object) {
const node = ((element: any): TextAreaWithWrapperState);
invariant(
props.dangerouslySetInnerHTML == null,
'`dangerouslySetInnerHTML` does not make sense on <textarea>.',
'`dangerouslySetInnerHTML` does not make sense on <textarea>.%s',
getCurrentFiberStackAddendum() || '',
);

// Always set children to the same thing. In IE9, the selection range will
Expand Down
24 changes: 14 additions & 10 deletions packages/react-reconciler/src/ReactChildFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ if (__DEV__) {
'Each child in an array or iterator should have a unique ' +
'"key" prop. See https://fb.me/react-warning-keys for ' +
'more information.%s',
getCurrentFiberStackAddendum(),
getCurrentFiberStackAddendum() || '',
);
};
}
Expand All @@ -109,8 +109,9 @@ function coerceRef(current: Fiber | null, element: ReactElement) {
invariant(
inst,
'Missing owner for string ref %s. This error is likely caused by a ' +
'bug in React. Please file an issue.',
'bug in React. Please file an issue.%s',
mixedRef,
getCurrentFiberStackAddendum() || '',
);
const stringRef = '' + mixedRef;
// Check if previous string ref matches new string ref
Expand All @@ -134,7 +135,8 @@ function coerceRef(current: Fiber | null, element: ReactElement) {
} else {
invariant(
typeof mixedRef === 'string',
'Expected ref to be a function or a string.',
'Expected ref to be a function or a string.%s',
getCurrentFiberStackAddendum() || '',
);
invariant(
element._owner,
Expand All @@ -143,8 +145,9 @@ function coerceRef(current: Fiber | null, element: ReactElement) {
'1. You may be adding a ref to a functional component\n' +
"2. You may be adding a ref to a component that was not created inside a component's render method\n" +
'3. You have multiple copies of React loaded\n' +
'See https://fb.me/react-refs-must-have-owner for more information.',
'See https://fb.me/react-refs-must-have-owner for more information.%s',
mixedRef,
getCurrentFiberStackAddendum() || '',
);
}
}
Expand All @@ -157,16 +160,16 @@ function throwOnInvalidObjectType(returnFiber: Fiber, newChild: Object) {
if (__DEV__) {
addendum =
' If you meant to render a collection of children, use an array ' +
'instead.' +
(getCurrentFiberStackAddendum() || '');
'instead.';
}
invariant(
false,
'Objects are not valid as a React child (found: %s).%s',
'Objects are not valid as a React child (found: %s).%s%s',
Object.prototype.toString.call(newChild) === '[object Object]'
? 'object with keys {' + Object.keys(newChild).join(', ') + '}'
: newChild,
addendum,
getCurrentFiberStackAddendum() || '',
);
}
}
Expand Down Expand Up @@ -680,7 +683,7 @@ function ChildReconciler(shouldTrackSideEffects) {
'duplicated and/or omitted — the behavior is unsupported and ' +
'could change in a future version.%s',
key,
getCurrentFiberStackAddendum(),
getCurrentFiberStackAddendum() || '',
);
break;
default:
Expand Down Expand Up @@ -862,7 +865,8 @@ function ChildReconciler(shouldTrackSideEffects) {
invariant(
typeof iteratorFn === 'function',
'An object is not an iterable. This error is likely caused by a bug in ' +
'React. Please file an issue.',
'React. Please file an issue.%s',
getCurrentFiberStackAddendum() || '',
);

if (__DEV__) {
Expand All @@ -875,7 +879,7 @@ function ChildReconciler(shouldTrackSideEffects) {
'Using Maps as children is unsupported and will likely yield ' +
'unexpected results. Convert it to a sequence/iterable of keyed ' +
'ReactElements instead.%s',
getCurrentFiberStackAddendum(),
getCurrentFiberStackAddendum() || '',
);
didWarnAboutMaps = true;
}
Expand Down
6 changes: 5 additions & 1 deletion packages/react-reconciler/src/ReactFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import type {TypeOfInternalContext} from './ReactTypeOfInternalContext';
import type {TypeOfSideEffect} from 'shared/ReactTypeOfSideEffect';
import type {ExpirationTime} from './ReactFiberExpirationTime';
import type {UpdateQueue} from './ReactFiberUpdateQueue';
import ReactDebugCurrentFiber from './ReactDebugCurrentFiber';

const {getCurrentFiberStackAddendum} = ReactDebugCurrentFiber;

import invariant from 'fbjs/lib/invariant';
import {NoEffect} from 'shared/ReactTypeOfSideEffect';
Expand Down Expand Up @@ -390,9 +393,10 @@ export function createFiberFromElement(
false,
'Element type is invalid: expected a string (for built-in ' +
'components) or a class/function (for composite components) ' +
'but got: %s.%s',
'but got: %s.%s%s',
type == null ? type : typeof type,
info,
getCurrentFiberStackAddendum() || '',
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ describe('ReactIncrementalErrorHandling', () => {
return {type: 'span', children: [], prop};
}

function removeStack(str) {
return str && str.replace(/in .+? \(at .+?:\d+\)/g, '').trim();
}

function stripStackTrace(compSpan) {
let [first, ...rest] = compSpan;
return [
...rest,
{
...first,
prop: removeStack(first.prop) || '',
},
];
}

it('catches render error in a boundary during full deferred mounting', () => {
class ErrorBoundary extends React.Component {
state = {error: null};
Expand Down Expand Up @@ -745,7 +760,7 @@ describe('ReactIncrementalErrorHandling', () => {
expect(ReactNoop.flush).toWarnDev(
'Warning: React.createElement: type is invalid -- expected a string',
);
expect(ReactNoop.getChildren()).toEqual([
expect(stripStackTrace(ReactNoop.getChildren())).toEqual([
span(
'Element type is invalid: expected a string (for built-in components) or ' +
'a class/function (for composite components) but got: undefined.' +
Expand Down Expand Up @@ -792,7 +807,7 @@ describe('ReactIncrementalErrorHandling', () => {
expect(ReactNoop.flush).toWarnDev(
'Warning: React.createElement: type is invalid -- expected a string',
);
expect(ReactNoop.getChildren()).toEqual([
expect(stripStackTrace(ReactNoop.getChildren())).toEqual([
span(
'Element type is invalid: expected a string (for built-in components) or ' +
'a class/function (for composite components) but got: undefined.' +
Expand Down