Replace throw new Error with invariant module

This commit is contained in:
Andrew Clark
2017-02-06 14:43:14 -08:00
parent fa1087b42c
commit a1ef4c4391
7 changed files with 154 additions and 97 deletions
+12 -9
View File
@@ -797,17 +797,19 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
// but using the iterator instead.
const iteratorFn = getIteratorFn(newChildrenIterable);
if (typeof iteratorFn !== 'function') {
throw new Error('An object is not an iterable.');
}
invariant(
typeof iteratorFn === 'function',
'An object is not an iterable.'
);
if (__DEV__) {
// First, validate keys.
// We'll get a different iterator later for the main pass.
const newChildren = iteratorFn.call(newChildrenIterable);
if (newChildren == null) {
throw new Error('An iterable object provided no iterator.');
}
invariant(
newChildren != null,
'An iterable object provided no iterator.'
);
let knownKeys = null;
let step = newChildren.next();
for (; !step.done; step = newChildren.next()) {
@@ -817,9 +819,10 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
}
const newChildren = iteratorFn.call(newChildrenIterable);
if (newChildren == null) {
throw new Error('An iterable object provided no iterator.');
}
invariant(
newChildren != null,
'An iterable object provided no iterator.'
);
let resultingFirstChild : ?Fiber = null;
let previousNewFiber : ?Fiber = null;
@@ -62,10 +62,11 @@ var {
} = require('ReactTypeOfSideEffect');
var ReactCurrentOwner = require('ReactCurrentOwner');
var ReactFiberClassComponent = require('ReactFiberClassComponent');
var warning = require('warning');
var invariant = require('invariant');
if (__DEV__) {
var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber');
var warning = require('warning');
var warnedAboutStatelessRefs = {};
}
@@ -341,9 +342,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
// we don't do the bailout and we have to reuse existing props instead.
if (nextProps === null) {
nextProps = memoizedProps;
if (!nextProps) {
throw new Error('We should always have pending or current props.');
}
invariant(
nextProps !== null,
'We should always have pending or current props.'
);
}
} else if (nextProps === null || memoizedProps === nextProps) {
if (memoizedProps.hidden &&
@@ -442,9 +444,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
}
function mountIndeterminateComponent(current, workInProgress, priorityLevel) {
if (current) {
throw new Error('An indeterminate component should never have mounted.');
}
invariant(
current === null,
'An indeterminate component should never have mounted'
);
var fn = workInProgress.type;
var props = workInProgress.pendingProps;
var unmaskedContext = getUnmaskedContext(workInProgress);
@@ -511,9 +514,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
// we don't do the bailout and we have to reuse existing props instead.
if (nextCoroutine === null) {
nextCoroutine = current && current.memoizedProps;
if (!nextCoroutine) {
throw new Error('We should always have pending or current props.');
}
invariant(
nextCoroutine != null,
'We should always have pending or current props.'
);
}
} else if (nextCoroutine === null || workInProgress.memoizedProps === nextCoroutine) {
nextCoroutine = workInProgress.memoizedProps;
@@ -575,9 +579,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
// we don't do the bailout and we have to reuse existing props instead.
if (nextChildren === null) {
nextChildren = current && current.memoizedProps;
if (!nextChildren) {
throw new Error('We should always have pending or current props.');
}
invariant(
nextChildren != null,
'We should always have pending or current props.'
);
}
} else if (nextChildren === null || workInProgress.memoizedProps === nextChildren) {
return bailoutOnAlreadyFinishedWork(current, workInProgress);
@@ -727,15 +732,16 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
case Fragment:
return updateFragment(current, workInProgress);
default:
throw new Error('Unknown unit of work tag');
invariant(false, 'Unknown unit of work tag');
}
}
function beginFailedWork(current : ?Fiber, workInProgress : Fiber, priorityLevel : PriorityLevel) {
if (workInProgress.tag !== ClassComponent &&
workInProgress.tag !== HostRoot) {
throw new Error('Invalid type of work');
}
invariant(
workInProgress.tag === ClassComponent ||
workInProgress.tag === HostRoot,
'Invalid type of work'
);
// Add an error effect so we can handle the error during the commit phase
workInProgress.effectTag |= Err;
@@ -257,9 +257,10 @@ module.exports = function(
const state = instance.state || null;
let props = workInProgress.pendingProps;
if (!props) {
throw new Error('There must be pending props for an initial mount.');
}
invariant(
props,
'There must be pending props for an initial mount.'
);
const unmaskedContext = getUnmaskedContext(workInProgress);
@@ -298,9 +299,10 @@ module.exports = function(
// If there isn't any new props, then we'll reuse the memoized props.
// This could be from already completed work.
newProps = workInProgress.memoizedProps;
if (!newProps) {
throw new Error('There should always be pending or memoized props.');
}
invariant(
newProps != null,
'There should always be pending or memoized props.'
);
}
const newUnmaskedContext = getUnmaskedContext(workInProgress);
const newContext = getMaskedContext(workInProgress, newUnmaskedContext);
@@ -363,9 +365,10 @@ module.exports = function(
// If there aren't any new props, then we'll reuse the memoized props.
// This could be from already completed work.
newProps = oldProps;
if (!newProps) {
throw new Error('There should always be pending or memoized props.');
}
invariant(
newProps != null,
'There should always be pending or memoized props.'
);
}
const oldContext = instance.context;
const newUnmaskedContext = getUnmaskedContext(workInProgress);
@@ -34,6 +34,8 @@ var {
ContentReset,
} = require('ReactTypeOfSideEffect');
var invariant = require('invariant');
module.exports = function<T, P, I, TI, PI, C, CX, PL>(
config : HostConfig<T, P, I, TI, PI, C, CX, PL>,
captureError : (failedFiber : Fiber, error: Error) => ?Fiber
@@ -94,7 +96,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
}
parent = parent.return;
}
throw new Error('Expected to find a host parent.');
invariant(
false,
'Expected to find a host parent.'
);
}
function getHostParentFiber(fiber : Fiber) : Fiber {
@@ -105,7 +110,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
}
parent = parent.return;
}
throw new Error('Expected to find a host parent.');
invariant(
false,
'Expected to find a host parent.'
);
}
function isHostParent(fiber : Fiber) : boolean {
@@ -173,7 +181,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
parent = parentFiber.stateNode.containerInfo;
break;
default:
throw new Error('Invalid host parent fiber.');
invariant(
false,
'Invalid host parent fiber.'
);
}
if (parentFiber.effectTag & ContentReset) {
// 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>(
return;
}
case HostText: {
if (finishedWork.stateNode == null || !current) {
throw new Error('This should only be done during updates.');
}
invariant(
finishedWork.stateNode !== null && current != null,
'This should only be done during updates.'
);
const textInstance : TI = finishedWork.stateNode;
const newText : string = finishedWork.memoizedProps;
const oldText : string = current.memoizedProps;
@@ -389,8 +401,12 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
case HostPortal: {
return;
}
default:
throw new Error('This unit of work tag should not have side-effects.');
default: {
invariant(
false,
'This unit of work tag should not have side-effects.'
);
}
}
}
@@ -450,8 +466,12 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
// We have no life-cycles associated with portals.
return;
}
default:
throw new Error('This unit of work tag should not have side-effects.');
default: {
invariant(
false,
'This unit of work tag should not have side-effects.'
);
}
}
}
@@ -46,6 +46,8 @@ if (__DEV__) {
var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber');
}
var invariant = require('invariant');
module.exports = function<T, P, I, TI, PI, C, CX, PL>(
config : HostConfig<T, P, I, TI, PI, C, CX, PL>,
hostContext : HostContext<C, CX>,
@@ -91,7 +93,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
while (node) {
if (node.tag === HostComponent || node.tag === HostText ||
node.tag === HostPortal) {
throw new Error('A coroutine cannot have host component children.');
invariant(
false,
'A coroutine cannot have host component children.'
);
} else if (node.tag === YieldComponent) {
yields.push(node.type);
} else if (node.child) {
@@ -112,9 +117,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
function moveCoroutineToHandlerPhase(current : ?Fiber, workInProgress : Fiber) {
var coroutine = (workInProgress.memoizedProps : ?ReactCoroutine);
if (!coroutine) {
throw new Error('Should be resolved by now');
}
invariant(
coroutine,
'Should be resolved by now'
);
// First step of the coroutine has completed. Now we need to do the second.
// 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>(
}
} else {
if (!newProps) {
if (workInProgress.stateNode === null) {
throw new Error('We must have new props for new mounts.');
} else {
// This can happen when we abort work.
return null;
}
invariant(
workInProgress.stateNode !== null,
'We must have new props for new mounts'
);
// This can happen when we abort work.
return null;
}
const currentHostContext = getHostContext();
@@ -278,12 +284,12 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
}
} else {
if (typeof newText !== 'string') {
if (workInProgress.stateNode === null) {
throw new Error('We must have new props for new mounts.');
} else {
// This can happen when we abort work.
return null;
}
invariant(
workInProgress.stateNode !== null,
'We must have new props for new mounts'
);
// This can happen when we abort work.
return null;
}
const rootContainerInstance = getRootHostContainer();
const currentHostContext = getHostContext();
@@ -311,9 +317,16 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
// Error cases
case IndeterminateComponent:
throw new Error('An indeterminate component should have become determinate before completing.');
invariant(
false,
'An indeterminate component should have become determinate before completing.'
);
// eslint-disable-next-line no-fallthrough
default:
throw new Error('Unknown unit of work tag');
invariant(
false,
'Unknown unit of work tag'
);
}
}
@@ -24,6 +24,8 @@ const {
push,
} = require('ReactFiberStack');
const invariant = require('invariant');
export type HostContext<C, CX> = {
getHostContext() : CX,
getRootHostContainer() : C,
@@ -48,9 +50,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
function getRootHostContainer() : C {
const rootInstance = rootInstanceStackCursor.current;
if (rootInstance == null) {
throw new Error('Expected root container to exist.');
}
invariant(
rootInstance != null,
'Expected root container to exist.'
);
return rootInstance;
}
@@ -75,17 +78,19 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
function getHostContext() : CX {
const context = contextStackCursor.current;
if (context == null) {
throw new Error('Expected host context to exist.');
}
invariant(
context != null,
'Expected host context to exist.'
);
return context;
}
function pushHostContext(fiber : Fiber) : void {
const rootInstance = rootInstanceStackCursor.current;
if (rootInstance == null) {
throw new Error('Expected root host context to exist.');
}
invariant(
rootInstance != null,
'Expected root host context to exist.'
);
const context = contextStackCursor.current || emptyObject;
const nextContext = getChildHostContext(context, fiber.type, rootInstance);
@@ -83,6 +83,8 @@ var {
resetContext,
} = require('ReactFiberContext');
var invariant = require('invariant');
if (__DEV__) {
var ReactFiberInstrumentation = require('ReactFiberInstrumentation');
var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber');
@@ -340,12 +342,11 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
pendingCommit = null;
const root : FiberRoot = (finishedWork.stateNode : any);
if (root.current === finishedWork) {
throw new Error(
'Cannot commit the same tree as before. This is probably a bug ' +
'related to the return field.'
);
}
invariant(
root.current !== finishedWork,
'Cannot commit the same tree as before. This is probably a bug ' +
'related to the return field.'
);
// Updates that occur during the commit phase should have Task priority
const previousPriorityContext = priorityContext;
@@ -378,9 +379,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
try {
commitAllHostEffects(finishedWork);
} catch (error) {
if (!nextEffect) {
throw new Error('Should have nextEffect.');
}
invariant(
nextEffect != null,
'Should have next effect.'
);
captureError(nextEffect, error);
// Clean-up
if (nextEffect) {
@@ -406,9 +408,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
try {
commitAllLifeCycles(finishedWork, nextEffect);
} catch (error) {
if (!nextEffect) {
throw new Error('Should have nextEffect.');
}
invariant(
nextEffect != null,
'Should have next effect.'
);
captureError(nextEffect, error);
if (nextEffect) {
nextEffect = nextEffect.nextEffect;
@@ -705,9 +708,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
}
function performWork(priorityLevel : PriorityLevel, deadline : Deadline | null) {
if (isPerformingWork) {
throw new Error('performWork was called recursively.');
}
invariant(
!isPerformingWork,
'performWork was called recursively.'
);
isPerformingWork = true;
const isPerformingDeferredWork = Boolean(deadline);
let deadlineHasExpired = false;
@@ -716,11 +720,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
// catching an error. It also lets us flush Task work at the end of a
// deferred batch.
while (priorityLevel !== NoWork && !fatalError) {
if (priorityLevel >= HighPriority && !deadline) {
throw new Error(
'Cannot perform deferred work without a deadline.'
);
}
invariant(
deadline || (priorityLevel < HighPriority),
'Cannot perform deferred work without a deadline.'
);
// Before starting any work, check to see if there are any pending
// commits from the previous frame.
@@ -988,9 +991,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
}
}
if (!capturedError) {
throw new Error('No error for given unit of work.');
}
invariant(
capturedError != null,
'No error for given unit of work.'
);
let error;
@@ -1023,7 +1027,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
}
return;
default:
throw new Error('Invalid type of work.');
invariant(
false,
'Invalid type of work.'
);
}
}