Include owner in invalid element type invariant (#8637)
Dan Abramov committed
Dec 27, 2016 at 08:41 UTC
6b7307355758a49ef8909160200ae9f70f827a2d
5 files changed
+30
-12
scripts/fiber/tests-failing.txt
-6
@@ -9,9 +9,6 @@ src/addons/__tests__/ReactFragment-test.js
9
src/isomorphic/classic/__tests__/ReactContextValidator-test.js
10
* should pass previous context to lifecycles
11
12
-src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js
13
-* includes the owner name when passing null, undefined, boolean, or number
14
-
12
src/renderers/dom/__tests__/ReactDOMProduction-test.js
13
* should throw with an error code in production
14
@@ -63,9 +60,6 @@ src/renderers/shared/hooks/__tests__/ReactComponentTreeHook-test.js
60
src/renderers/shared/hooks/__tests__/ReactHostOperationHistoryHook-test.js
61
* gets recorded during an update
62
66
-src/renderers/shared/shared/__tests__/ReactComponent-test.js
67
-* includes owner name in the error about badly-typed elements
68
-
63
src/renderers/shared/shared/__tests__/ReactComponentLifeCycle-test.js
64
* should carry through each of the phases of setup
65
scripts/fiber/tests-passing.txt
+2
@@ -287,6 +287,7 @@ src/isomorphic/classic/element/__tests__/ReactElementValidator-test.js
287
* does not warn when the array contains a non-element
288
* should give context for PropType errors in nested components.
289
* gives a helpful error when passing invalid types
290
+* includes the owner name when passing null, undefined, boolean, or number
291
* should check default prop values
292
* should not check the default for explicit null
293
* should check declared prop types
@@ -1334,6 +1335,7 @@ src/renderers/shared/shared/__tests__/ReactComponent-test.js
1335
* should call refs at the correct time
1336
* fires the callback after a component is rendered
1337
* throws usefully when rendering badly-typed elements
1338
+* includes owner name in the error about badly-typed elements
1339
1340
src/renderers/shared/shared/__tests__/ReactComponentLifeCycle-test.js
1341
* should not reuse an instance when it has been unmounted
src/renderers/shared/fiber/ReactDebugCurrentFiber.js
+18
-3
@@ -15,6 +15,12 @@
15
import type { Fiber } from 'ReactFiber';
16
17
if (__DEV__) {
18
+ var {
19
+ IndeterminateComponent,
20
+ FunctionalComponent,
21
+ ClassComponent,
22
+ HostComponent,
23
+ } = require('ReactTypeOfWork');
24
var getComponentName = require('getComponentName');
25
var { getStackAddendumByWorkInProgressFiber } = require('ReactComponentTreeHook');
26
}
@@ -25,10 +31,19 @@ function getCurrentFiberOwnerName() : string | null {
31
if (fiber == null) {
32
return null;
33
}
28
- if (fiber._debugOwner == null) {
29
- return null;
34
+ switch (fiber.tag) {
35
+ case IndeterminateComponent:
36
+ case FunctionalComponent:
37
+ case ClassComponent:
38
+ return getComponentName(fiber);
39
+ case HostComponent:
40
+ if (fiber._debugOwner != null) {
41
+ return getComponentName(fiber._debugOwner);
42
+ }
43
+ return null;
44
+ default:
45
+ return null;
46
}
31
- return getComponentName(fiber._debugOwner);
47
}
48
return null;
49
}
src/renderers/shared/fiber/ReactFiber.js
+8
-1
@@ -49,6 +49,10 @@ var {
49
50
var invariant = require('invariant');
51
52
+if (__DEV__) {
53
+ var { getCurrentFiberOwnerName } = require('ReactDebugCurrentFiber');
54
+}
55
+
56
// A Fiber is work on a Component that needs to be done or was done. There can
57
// be more than one per component.
58
export type Fiber = {
@@ -359,8 +363,11 @@ function createFiberFromElementType(type : mixed, key : null | string) : Fiber {
363
' You likely forgot to export your component from the file ' +
364
'it\'s defined in.';
365
}
366
+ const ownerName = getCurrentFiberOwnerName();
367
+ if (ownerName) {
368
+ info += ' Check the render method of `' + ownerName + '`.';
369
+ }
370
}
363
- // TODO: Stack also includes owner name in the message.
371
invariant(
372
false,
373
'Element type is invalid: expected a string (for built-in components) ' +
src/renderers/shared/fiber/__tests__/ReactIncrementalErrorHandling-test.js
+2
-2
@@ -754,7 +754,7 @@ describe('ReactIncrementalErrorHandling', () => {
754
'Element type is invalid: expected a string (for built-in components) or ' +
755
'a class/function (for composite components) but got: undefined. ' +
756
'You likely forgot to export your component from the file it\'s ' +
757
- 'defined in.'
757
+ 'defined in. Check the render method of `BrokenRender`.'
758
)]);
759
expect(console.error.calls.count()).toBe(1);
760
});
@@ -798,7 +798,7 @@ describe('ReactIncrementalErrorHandling', () => {
798
'Element type is invalid: expected a string (for built-in components) or ' +
799
'a class/function (for composite components) but got: undefined. ' +
800
'You likely forgot to export your component from the file it\'s ' +
801
- 'defined in.'
801
+ 'defined in. Check the render method of `BrokenRender`.'
802
)]);
803
expect(console.error.calls.count()).toBe(1);
804
});