@samitouri / QOS-React / commits / a1ef4c4391

Replace `throw new Error` with invariant module

Andrew Clark committed Feb 3, 2017 at 13:32 UTC a1ef4c43913c2febcb0eef5d6070b666e81aa233
7 files changed +154 -97
src/renderers/shared/fiber/ReactChildFiber.js
+12 -9
@@ -797,17 +797,19 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
797 // but using the iterator instead.
798
799 const iteratorFn = getIteratorFn(newChildrenIterable);
800 - if (typeof iteratorFn !== 'function') {
801 - throw new Error('An object is not an iterable.');
802 - }
800 + invariant(
801 + typeof iteratorFn === 'function',
802 + 'An object is not an iterable.'
803 + );
804
805 if (__DEV__) {
806 // First, validate keys.
807 // We'll get a different iterator later for the main pass.
808 const newChildren = iteratorFn.call(newChildrenIterable);
808 - if (newChildren == null) {
809 - throw new Error('An iterable object provided no iterator.');
810 - }
809 + invariant(
810 + newChildren != null,
811 + 'An iterable object provided no iterator.'
812 + );
813 let knownKeys = null;
814 let step = newChildren.next();
815 for (; !step.done; step = newChildren.next()) {
@@ -817,9 +819,10 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
819 }
820
821 const newChildren = iteratorFn.call(newChildrenIterable);
820 - if (newChildren == null) {
821 - throw new Error('An iterable object provided no iterator.');
822 - }
822 + invariant(
823 + newChildren != null,
824 + 'An iterable object provided no iterator.'
825 + );
826
827 let resultingFirstChild : ?Fiber = null;
828 let previousNewFiber : ?Fiber = null;
src/renderers/shared/fiber/ReactFiberBeginWork.js
+24 -18
@@ -62,10 +62,11 @@ var {
62 } = require('ReactTypeOfSideEffect');
63 var ReactCurrentOwner = require('ReactCurrentOwner');
64 var ReactFiberClassComponent = require('ReactFiberClassComponent');
65 -var warning = require('warning');
65 +var invariant = require('invariant');
66
67 if (__DEV__) {
68 var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber');
69 + var warning = require('warning');
70
71 var warnedAboutStatelessRefs = {};
72 }
@@ -341,9 +342,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
342 // we don't do the bailout and we have to reuse existing props instead.
343 if (nextProps === null) {
344 nextProps = memoizedProps;
344 - if (!nextProps) {
345 - throw new Error('We should always have pending or current props.');
346 - }
345 + invariant(
346 + nextProps !== null,
347 + 'We should always have pending or current props.'
348 + );
349 }
350 } else if (nextProps === null || memoizedProps === nextProps) {
351 if (memoizedProps.hidden &&
@@ -442,9 +444,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
444 }
445
446 function mountIndeterminateComponent(current, workInProgress, priorityLevel) {
445 - if (current) {
446 - throw new Error('An indeterminate component should never have mounted.');
447 - }
447 + invariant(
448 + current === null,
449 + 'An indeterminate component should never have mounted'
450 + );
451 var fn = workInProgress.type;
452 var props = workInProgress.pendingProps;
453 var unmaskedContext = getUnmaskedContext(workInProgress);
@@ -511,9 +514,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
514 // we don't do the bailout and we have to reuse existing props instead.
515 if (nextCoroutine === null) {
516 nextCoroutine = current && current.memoizedProps;
514 - if (!nextCoroutine) {
515 - throw new Error('We should always have pending or current props.');
516 - }
517 + invariant(
518 + nextCoroutine != null,
519 + 'We should always have pending or current props.'
520 + );
521 }
522 } else if (nextCoroutine === null || workInProgress.memoizedProps === nextCoroutine) {
523 nextCoroutine = workInProgress.memoizedProps;
@@ -575,9 +579,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
579 // we don't do the bailout and we have to reuse existing props instead.
580 if (nextChildren === null) {
581 nextChildren = current && current.memoizedProps;
578 - if (!nextChildren) {
579 - throw new Error('We should always have pending or current props.');
580 - }
582 + invariant(
583 + nextChildren != null,
584 + 'We should always have pending or current props.'
585 + );
586 }
587 } else if (nextChildren === null || workInProgress.memoizedProps === nextChildren) {
588 return bailoutOnAlreadyFinishedWork(current, workInProgress);
@@ -727,15 +732,16 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
732 case Fragment:
733 return updateFragment(current, workInProgress);
734 default:
730 - throw new Error('Unknown unit of work tag');
735 + invariant(false, 'Unknown unit of work tag');
736 }
737 }
738
739 function beginFailedWork(current : ?Fiber, workInProgress : Fiber, priorityLevel : PriorityLevel) {
735 - if (workInProgress.tag !== ClassComponent &&
736 - workInProgress.tag !== HostRoot) {
737 - throw new Error('Invalid type of work');
738 - }
740 + invariant(
741 + workInProgress.tag === ClassComponent ||
742 + workInProgress.tag === HostRoot,
743 + 'Invalid type of work'
744 + );
745
746 // Add an error effect so we can handle the error during the commit phase
747 workInProgress.effectTag |= Err;
src/renderers/shared/fiber/ReactFiberClassComponent.js
+12 -9
@@ -257,9 +257,10 @@ module.exports = function(
257 const state = instance.state || null;
258
259 let props = workInProgress.pendingProps;
260 - if (!props) {
261 - throw new Error('There must be pending props for an initial mount.');
262 - }
260 + invariant(
261 + props,
262 + 'There must be pending props for an initial mount.'
263 + );
264
265 const unmaskedContext = getUnmaskedContext(workInProgress);
266
@@ -298,9 +299,10 @@ module.exports = function(
299 // If there isn't any new props, then we'll reuse the memoized props.
300 // This could be from already completed work.
301 newProps = workInProgress.memoizedProps;
301 - if (!newProps) {
302 - throw new Error('There should always be pending or memoized props.');
303 - }
302 + invariant(
303 + newProps != null,
304 + 'There should always be pending or memoized props.'
305 + );
306 }
307 const newUnmaskedContext = getUnmaskedContext(workInProgress);
308 const newContext = getMaskedContext(workInProgress, newUnmaskedContext);
@@ -363,9 +365,10 @@ module.exports = function(
365 // If there aren't any new props, then we'll reuse the memoized props.
366 // This could be from already completed work.
367 newProps = oldProps;
366 - if (!newProps) {
367 - throw new Error('There should always be pending or memoized props.');
368 - }
368 + invariant(
369 + newProps != null,
370 + 'There should always be pending or memoized props.'
371 + );
372 }
373 const oldContext = instance.context;
374 const newUnmaskedContext = getUnmaskedContext(workInProgress);
src/renderers/shared/fiber/ReactFiberCommitWork.js
+30 -10
@@ -34,6 +34,8 @@ var {
34 ContentReset,
35 } = require('ReactTypeOfSideEffect');
36
37 +var invariant = require('invariant');
38 +
39 module.exports = function<T, P, I, TI, PI, C, CX, PL>(
40 config : HostConfig<T, P, I, TI, PI, C, CX, PL>,
41 captureError : (failedFiber : Fiber, error: Error) => ?Fiber
@@ -94,7 +96,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
96 }
97 parent = parent.return;
98 }
97 - throw new Error('Expected to find a host parent.');
99 + invariant(
100 + false,
101 + 'Expected to find a host parent.'
102 + );
103 }
104
105 function getHostParentFiber(fiber : Fiber) : Fiber {
@@ -105,7 +110,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
110 }
111 parent = parent.return;
112 }
108 - throw new Error('Expected to find a host parent.');
113 + invariant(
114 + false,
115 + 'Expected to find a host parent.'
116 + );
117 }
118
119 function isHostParent(fiber : Fiber) : boolean {
@@ -173,7 +181,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
181 parent = parentFiber.stateNode.containerInfo;
182 break;
183 default:
176 - throw new Error('Invalid host parent fiber.');
184 + invariant(
185 + false,
186 + 'Invalid host parent fiber.'
187 + );
188 }
189 if (parentFiber.effectTag & ContentReset) {
190 // Reset the text content of the parent before doing any insertions
@@ -374,9 +385,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
385 return;
386 }
387 case HostText: {
377 - if (finishedWork.stateNode == null || !current) {
378 - throw new Error('This should only be done during updates.');
379 - }
388 + invariant(
389 + finishedWork.stateNode !== null && current != null,
390 + 'This should only be done during updates.'
391 + );
392 const textInstance : TI = finishedWork.stateNode;
393 const newText : string = finishedWork.memoizedProps;
394 const oldText : string = current.memoizedProps;
@@ -389,8 +401,12 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
401 case HostPortal: {
402 return;
403 }
392 - default:
393 - throw new Error('This unit of work tag should not have side-effects.');
404 + default: {
405 + invariant(
406 + false,
407 + 'This unit of work tag should not have side-effects.'
408 + );
409 + }
410 }
411 }
412
@@ -450,8 +466,12 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
466 // We have no life-cycles associated with portals.
467 return;
468 }
453 - default:
454 - throw new Error('This unit of work tag should not have side-effects.');
469 + default: {
470 + invariant(
471 + false,
472 + 'This unit of work tag should not have side-effects.'
473 + );
474 + }
475 }
476 }
477
src/renderers/shared/fiber/ReactFiberCompleteWork.js
+31 -18
@@ -46,6 +46,8 @@ if (__DEV__) {
46 var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber');
47 }
48
49 +var invariant = require('invariant');
50 +
51 module.exports = function<T, P, I, TI, PI, C, CX, PL>(
52 config : HostConfig<T, P, I, TI, PI, C, CX, PL>,
53 hostContext : HostContext<C, CX>,
@@ -91,7 +93,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
93 while (node) {
94 if (node.tag === HostComponent || node.tag === HostText ||
95 node.tag === HostPortal) {
94 - throw new Error('A coroutine cannot have host component children.');
96 + invariant(
97 + false,
98 + 'A coroutine cannot have host component children.'
99 + );
100 } else if (node.tag === YieldComponent) {
101 yields.push(node.type);
102 } else if (node.child) {
@@ -112,9 +117,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
117
118 function moveCoroutineToHandlerPhase(current : ?Fiber, workInProgress : Fiber) {
119 var coroutine = (workInProgress.memoizedProps : ?ReactCoroutine);
115 - if (!coroutine) {
116 - throw new Error('Should be resolved by now');
117 - }
120 + invariant(
121 + coroutine,
122 + 'Should be resolved by now'
123 + );
124
125 // First step of the coroutine has completed. Now we need to do the second.
126 // TODO: It would be nice to have a multi stage coroutine represented by a
@@ -229,12 +235,12 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
235 }
236 } else {
237 if (!newProps) {
232 - if (workInProgress.stateNode === null) {
233 - throw new Error('We must have new props for new mounts.');
234 - } else {
235 - // This can happen when we abort work.
236 - return null;
237 - }
238 + invariant(
239 + workInProgress.stateNode !== null,
240 + 'We must have new props for new mounts'
241 + );
242 + // This can happen when we abort work.
243 + return null;
244 }
245
246 const currentHostContext = getHostContext();
@@ -278,12 +284,12 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
284 }
285 } else {
286 if (typeof newText !== 'string') {
281 - if (workInProgress.stateNode === null) {
282 - throw new Error('We must have new props for new mounts.');
283 - } else {
284 - // This can happen when we abort work.
285 - return null;
286 - }
287 + invariant(
288 + workInProgress.stateNode !== null,
289 + 'We must have new props for new mounts'
290 + );
291 + // This can happen when we abort work.
292 + return null;
293 }
294 const rootContainerInstance = getRootHostContainer();
295 const currentHostContext = getHostContext();
@@ -311,9 +317,16 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
317
318 // Error cases
319 case IndeterminateComponent:
314 - throw new Error('An indeterminate component should have become determinate before completing.');
320 + invariant(
321 + false,
322 + 'An indeterminate component should have become determinate before completing.'
323 + );
324 + // eslint-disable-next-line no-fallthrough
325 default:
316 - throw new Error('Unknown unit of work tag');
326 + invariant(
327 + false,
328 + 'Unknown unit of work tag'
329 + );
330 }
331 }
332
src/renderers/shared/fiber/ReactFiberHostContext.js
+14 -9
@@ -24,6 +24,8 @@ const {
24 push,
25 } = require('ReactFiberStack');
26
27 +const invariant = require('invariant');
28 +
29 export type HostContext<C, CX> = {
30 getHostContext() : CX,
31 getRootHostContainer() : C,
@@ -48,9 +50,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
50
51 function getRootHostContainer() : C {
52 const rootInstance = rootInstanceStackCursor.current;
51 - if (rootInstance == null) {
52 - throw new Error('Expected root container to exist.');
53 - }
53 + invariant(
54 + rootInstance != null,
55 + 'Expected root container to exist.'
56 + );
57 return rootInstance;
58 }
59
@@ -75,17 +78,19 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
78
79 function getHostContext() : CX {
80 const context = contextStackCursor.current;
78 - if (context == null) {
79 - throw new Error('Expected host context to exist.');
80 - }
81 + invariant(
82 + context != null,
83 + 'Expected host context to exist.'
84 + );
85 return context;
86 }
87
88 function pushHostContext(fiber : Fiber) : void {
89 const rootInstance = rootInstanceStackCursor.current;
86 - if (rootInstance == null) {
87 - throw new Error('Expected root host context to exist.');
88 - }
90 + invariant(
91 + rootInstance != null,
92 + 'Expected root host context to exist.'
93 + );
94
95 const context = contextStackCursor.current || emptyObject;
96 const nextContext = getChildHostContext(context, fiber.type, rootInstance);
src/renderers/shared/fiber/ReactFiberScheduler.js
+31 -24
@@ -83,6 +83,8 @@ var {
83 resetContext,
84 } = require('ReactFiberContext');
85
86 +var invariant = require('invariant');
87 +
88 if (__DEV__) {
89 var ReactFiberInstrumentation = require('ReactFiberInstrumentation');
90 var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber');
@@ -340,12 +342,11 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
342
343 pendingCommit = null;
344 const root : FiberRoot = (finishedWork.stateNode : any);
343 - if (root.current === finishedWork) {
344 - throw new Error(
345 - 'Cannot commit the same tree as before. This is probably a bug ' +
346 - 'related to the return field.'
347 - );
348 - }
345 + invariant(
346 + root.current !== finishedWork,
347 + 'Cannot commit the same tree as before. This is probably a bug ' +
348 + 'related to the return field.'
349 + );
350
351 // Updates that occur during the commit phase should have Task priority
352 const previousPriorityContext = priorityContext;
@@ -378,9 +379,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
379 try {
380 commitAllHostEffects(finishedWork);
381 } catch (error) {
381 - if (!nextEffect) {
382 - throw new Error('Should have nextEffect.');
383 - }
382 + invariant(
383 + nextEffect != null,
384 + 'Should have next effect.'
385 + );
386 captureError(nextEffect, error);
387 // Clean-up
388 if (nextEffect) {
@@ -406,9 +408,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
408 try {
409 commitAllLifeCycles(finishedWork, nextEffect);
410 } catch (error) {
409 - if (!nextEffect) {
410 - throw new Error('Should have nextEffect.');
411 - }
411 + invariant(
412 + nextEffect != null,
413 + 'Should have next effect.'
414 + );
415 captureError(nextEffect, error);
416 if (nextEffect) {
417 nextEffect = nextEffect.nextEffect;
@@ -705,9 +708,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
708 }
709
710 function performWork(priorityLevel : PriorityLevel, deadline : Deadline | null) {
708 - if (isPerformingWork) {
709 - throw new Error('performWork was called recursively.');
710 - }
711 + invariant(
712 + !isPerformingWork,
713 + 'performWork was called recursively.'
714 + );
715 isPerformingWork = true;
716 const isPerformingDeferredWork = Boolean(deadline);
717 let deadlineHasExpired = false;
@@ -716,11 +720,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
720 // catching an error. It also lets us flush Task work at the end of a
721 // deferred batch.
722 while (priorityLevel !== NoWork && !fatalError) {
719 - if (priorityLevel >= HighPriority && !deadline) {
720 - throw new Error(
721 - 'Cannot perform deferred work without a deadline.'
722 - );
723 - }
723 + invariant(
724 + deadline || (priorityLevel < HighPriority),
725 + 'Cannot perform deferred work without a deadline.'
726 + );
727
728 // Before starting any work, check to see if there are any pending
729 // commits from the previous frame.
@@ -988,9 +991,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
991 }
992 }
993
991 - if (!capturedError) {
992 - throw new Error('No error for given unit of work.');
993 - }
994 + invariant(
995 + capturedError != null,
996 + 'No error for given unit of work.'
997 + );
998
999 let error;
1000
@@ -1023,7 +1027,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
1027 }
1028 return;
1029 default:
1026 - throw new Error('Invalid type of work.');
1030 + invariant(
1031 + false,
1032 + 'Invalid type of work.'
1033 + );
1034 }
1035 }
1036