Skip to content

Commit

Permalink
Convert all non-reachable exceptions into invariants
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanGoncharov committed Jul 31, 2019
1 parent e58762a commit d618603
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 30 deletions.
28 changes: 26 additions & 2 deletions resources/inline-invariant.js
Expand Up @@ -21,6 +21,7 @@ module.exports = function inlineInvariant(context) {
(%%cond%%) || devAssert(0, %%args%%)
`);

const t = context.types;
return {
visitor: {
CallExpression(path) {
Expand All @@ -38,13 +39,36 @@ module.exports = function inlineInvariant(context) {
const calleeName = node.callee.name;
if (calleeName === 'invariant') {
const [cond, args] = node.arguments;
path.addComment('leading', ' istanbul ignore next ');
path.replaceWith(invariantTemplate({ cond, args }));

// Check if it is unreachable invariant: "invariant(false, ...)"
if (cond.type === 'BooleanLiteral' && cond.value === false) {
addIstanbulIgnoreElse(path);
} else {
path.replaceWith(invariantTemplate({ cond, args }));
}
} else if (calleeName === 'devAssert') {
const [cond, args] = node.arguments;
path.replaceWith(assertTemplate({ cond, args }));
}

path.addComment('leading', ' istanbul ignore next ');
},
},
};

function addIstanbulIgnoreElse(path) {
const parentStatement = path.getStatementParent();
const previousStatement =
parentStatement.container[parentStatement.key - 1];
if (previousStatement.type === 'IfStatement') {
let lastIf = previousStatement;
while (lastIf.alternate && lastIf.alternate.type === 'IfStatement') {
lastIf = lastIf.alternate;
}
if (lastIf.alternate == null) {
t.addComment(lastIf, 'leading', ' istanbul ignore else ');
}
}
}
};

10 changes: 5 additions & 5 deletions src/execution/execute.js
Expand Up @@ -4,6 +4,7 @@ import { forEach, isCollection } from 'iterall';

import inspect from '../jsutils/inspect';
import memoize3 from '../jsutils/memoize3';
import invariant from '../jsutils/invariant';
import devAssert from '../jsutils/devAssert';
import isInvalid from '../jsutils/isInvalid';
import isNullish from '../jsutils/isNullish';
Expand Down Expand Up @@ -872,11 +873,10 @@ function completeValue(
}

// Not reachable. All possible output types have been considered.
/* istanbul ignore next */
throw new Error(
`Cannot complete value of unexpected output type: "${inspect(
(returnType: empty),
)}".`,
invariant(
false,
'Cannot complete value of unexpected output type: ' +
inspect((returnType: empty)),
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/type/introspection.js
Expand Up @@ -3,6 +3,7 @@
import objectValues from '../polyfills/objectValues';

import inspect from '../jsutils/inspect';
import invariant from '../jsutils/invariant';

import { print } from '../language/printer';
import { DirectiveLocation } from '../language/directiveLocation';
Expand Down Expand Up @@ -208,8 +209,7 @@ export const __Type = new GraphQLObjectType({
}

// Not reachable. All possible types have been considered.
/* istanbul ignore next */
throw new Error(`Unexpected type: "${inspect((type: empty))}".`);
invariant(false, `Unexpected type: "${inspect((type: empty))}".`);
},
},
name: {
Expand Down
4 changes: 2 additions & 2 deletions src/utilities/astFromValue.js
Expand Up @@ -5,6 +5,7 @@ import { forEach, isCollection } from 'iterall';
import objectValues from '../polyfills/objectValues';

import inspect from '../jsutils/inspect';
import invariant from '../jsutils/invariant';
import isNullish from '../jsutils/isNullish';
import isInvalid from '../jsutils/isInvalid';
import isObjectLike from '../jsutils/isObjectLike';
Expand Down Expand Up @@ -137,8 +138,7 @@ export function astFromValue(value: mixed, type: GraphQLInputType): ?ValueNode {
}

// Not reachable. All possible input types have been considered.
/* istanbul ignore next */
throw new Error(`Unexpected input type: "${inspect((type: empty))}".`);
invariant(false, 'Unexpected input type: ' + inspect((type: empty)));
}

/**
Expand Down
7 changes: 4 additions & 3 deletions src/utilities/buildASTSchema.js
Expand Up @@ -4,6 +4,7 @@ import objectValues from '../polyfills/objectValues';

import keyMap from '../jsutils/keyMap';
import inspect from '../jsutils/inspect';
import invariant from '../jsutils/invariant';
import devAssert from '../jsutils/devAssert';
import keyValMap from '../jsutils/keyValMap';
import { type ObjMap } from '../jsutils/ObjMap';
Expand Down Expand Up @@ -313,9 +314,9 @@ export class ASTDefinitionBuilder {
}

// Not reachable. All possible type definition nodes have been considered.
/* istanbul ignore next */
throw new Error(
`Unexpected type definition node: "${inspect((astNode: empty))}".`,
invariant(
false,
'Unexpected type definition node: ' + inspect((astNode: empty)),
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/utilities/coerceValue.js
Expand Up @@ -5,6 +5,7 @@ import { forEach, isCollection } from 'iterall';
import objectValues from '../polyfills/objectValues';

import inspect from '../jsutils/inspect';
import invariant from '../jsutils/invariant';
import didYouMean from '../jsutils/didYouMean';
import isObjectLike from '../jsutils/isObjectLike';
import suggestionList from '../jsutils/suggestionList';
Expand Down Expand Up @@ -195,8 +196,7 @@ export function coerceValue(
}

// Not reachable. All possible input types have been considered.
/* istanbul ignore next */
throw new Error(`Unexpected input type: "${inspect((type: empty))}".`);
invariant(false, 'Unexpected input type: ' + inspect((type: empty)));
}

function ofValue(value) {
Expand Down
4 changes: 2 additions & 2 deletions src/utilities/extendSchema.js
Expand Up @@ -5,6 +5,7 @@ import objectValues from '../polyfills/objectValues';

import inspect from '../jsutils/inspect';
import mapValue from '../jsutils/mapValue';
import invariant from '../jsutils/invariant';
import devAssert from '../jsutils/devAssert';
import keyValMap from '../jsutils/keyValMap';

Expand Down Expand Up @@ -258,8 +259,7 @@ export function extendSchema(
}

// Not reachable. All possible types have been considered.
/* istanbul ignore next */
throw new Error(`Unexpected type: "${inspect((type: empty))}".`);
invariant(false, 'Unexpected type: ' + inspect((type: empty)));
}

function extendDirective(directive: GraphQLDirective): GraphQLDirective {
Expand Down
3 changes: 1 addition & 2 deletions src/utilities/findBreakingChanges.js
Expand Up @@ -512,8 +512,7 @@ function typeKindName(type: GraphQLNamedType): string {
}

// Not reachable. All possible named types have been considered.
/* istanbul ignore next */
throw new TypeError(`Unexpected type: ${inspect((type: empty))}.`);
invariant(false, 'Unexpected type: ' + inspect((type: empty)));
}

function stringifyValue(value: mixed, type: GraphQLInputType): string {
Expand Down
4 changes: 2 additions & 2 deletions src/utilities/lexicographicSortSchema.js
Expand Up @@ -3,6 +3,7 @@
import objectValues from '../polyfills/objectValues';

import inspect from '../jsutils/inspect';
import invariant from '../jsutils/invariant';
import keyValMap from '../jsutils/keyValMap';
import { type ObjMap } from '../jsutils/ObjMap';

Expand Down Expand Up @@ -137,8 +138,7 @@ export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema {
}

// Not reachable. All possible types have been considered.
/* istanbul ignore next */
throw new Error(`Unexpected type: "${inspect((type: empty))}".`);
invariant(false, 'Unexpected type: ' + inspect((type: empty)));
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/utilities/schemaPrinter.js
Expand Up @@ -4,6 +4,7 @@ import flatMap from '../polyfills/flatMap';
import objectValues from '../polyfills/objectValues';

import inspect from '../jsutils/inspect';
import invariant from '../jsutils/invariant';

import { print } from '../language/printer';
import { printBlockString } from '../language/blockString';
Expand Down Expand Up @@ -173,8 +174,7 @@ export function printType(type: GraphQLNamedType, options?: Options): string {
}

// Not reachable. All possible types have been considered.
/* istanbul ignore next */
throw new Error(`Unexpected type: "${inspect((type: empty))}".`);
invariant(false, 'Unexpected type: ' + inspect((type: empty)));
}

function printScalar(type: GraphQLScalarType, options): string {
Expand Down
4 changes: 2 additions & 2 deletions src/utilities/typeFromAST.js
@@ -1,6 +1,7 @@
// @flow strict

import inspect from '../jsutils/inspect';
import invariant from '../jsutils/invariant';

import { Kind } from '../language/kinds';
import {
Expand Down Expand Up @@ -52,6 +53,5 @@ export function typeFromAST(schema, typeNode) {
}

// Not reachable. All possible type nodes have been considered.
/* istanbul ignore next */
throw new Error(`Unexpected type node: "${inspect((typeNode: empty))}".`);
invariant(false, 'Unexpected type node: ' + inspect((typeNode: empty)));
}
4 changes: 2 additions & 2 deletions src/utilities/valueFromAST.js
Expand Up @@ -4,6 +4,7 @@ import objectValues from '../polyfills/objectValues';

import keyMap from '../jsutils/keyMap';
import inspect from '../jsutils/inspect';
import invariant from '../jsutils/invariant';
import isInvalid from '../jsutils/isInvalid';
import { type ObjMap } from '../jsutils/ObjMap';

Expand Down Expand Up @@ -160,8 +161,7 @@ export function valueFromAST(
}

// Not reachable. All possible input types have been considered.
/* istanbul ignore next */
throw new Error(`Unexpected input type: "${inspect((type: empty))}".`);
invariant(false, 'Unexpected input type: ' + inspect((type: empty)));
}

// Returns true if the provided valueNode is a variable which is not defined
Expand Down
4 changes: 2 additions & 2 deletions src/utilities/valueFromASTUntyped.js
@@ -1,6 +1,7 @@
// @flow strict

import inspect from '../jsutils/inspect';
import invariant from '../jsutils/invariant';
import keyValMap from '../jsutils/keyValMap';
import isInvalid from '../jsutils/isInvalid';
import { type ObjMap } from '../jsutils/ObjMap';
Expand Down Expand Up @@ -56,6 +57,5 @@ export function valueFromASTUntyped(
}

// Not reachable. All possible value nodes have been considered.
/* istanbul ignore next */
throw new Error(`Unexpected value node: "${inspect((valueNode: empty))}".`);
invariant(false, 'Unexpected value node: ' + inspect((valueNode: empty)));
}

0 comments on commit d618603

Please sign in to comment.