Skip to content

Commit

Permalink
Add handling for invalid argument values, error reporting in getCompl…
Browse files Browse the repository at this point in the history
…exity function #61
  • Loading branch information
ivome committed Oct 21, 2021
1 parent a940f94 commit 7d045b1
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 21 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -2,3 +2,4 @@
node_modules
.DS_Store
.idea
.vscode
25 changes: 15 additions & 10 deletions README.md
Expand Up @@ -171,16 +171,21 @@ const query = parse(`
}
`);

const complexity = getComplexity({
estimators: [simpleEstimator({ defaultComplexity: 1 })],
schema,
query,
variables: {
count: 10,
},
});

console.log(complexity); // Output: 3
try {
const complexity = getComplexity({
estimators: [simpleEstimator({ defaultComplexity: 1 })],
schema,
query,
variables: {
count: 10,
},
});

console.log(complexity); // Output: 3
} catch (e) {
// Log error in case complexity cannot be calculated (invalid query, misconfiguration, etc.)
console.error('Could not calculate complexity', e.message);
}
```

## Prior Art
Expand Down
14 changes: 11 additions & 3 deletions src/QueryComplexity.ts
Expand Up @@ -96,11 +96,12 @@ export function getComplexity(options: {
}): number {
const typeInfo = new TypeInfo(options.schema);

const errors: GraphQLError[] = [];
const context = new ValidationContext(
options.schema,
options.query,
typeInfo,
() => null
(error) => errors.push(error)
);
const visitor = new QueryComplexity(context, {
// Maximum complexity does not matter since we're only interested in the calculated complexity.
Expand All @@ -111,6 +112,12 @@ export function getComplexity(options: {
});

visit(options.query, visitWithTypeInfo(typeInfo, visitor));

// Throw first error if any
if (errors.length) {
throw errors.pop();
}

return visitor.complexity;
}

Expand Down Expand Up @@ -244,7 +251,7 @@ export default class QueryComplexity {
(
complexities: ComplexityMap,
childNode: FieldNode | FragmentSpreadNode | InlineFragmentNode
) => {
): ComplexityMap => {
// let nodeComplexity = 0;
let innerComplexities = complexities;

Expand Down Expand Up @@ -297,7 +304,8 @@ export default class QueryComplexity {
this.variableValues || {}
);
} catch (e) {
return this.context.reportError(e);
this.context.reportError(e);
return complexities;
}

// Check if we have child complexity
Expand Down
52 changes: 44 additions & 8 deletions src/__tests__/QueryComplexity-test.ts
Expand Up @@ -2,7 +2,14 @@
* Created by Ivo Meißner on 28.07.17.
*/

import { parse, TypeInfo, visit, visitWithTypeInfo } from 'graphql';
import {
parse,
TypeInfo,
visit,
visitWithTypeInfo,
validate,
specifiedRules,
} from 'graphql';

import { expect } from 'chai';

Expand Down Expand Up @@ -523,7 +530,7 @@ describe('QueryComplexity analysis', () => {
);
});

it('should return NaN when no astNode available on field when using directiveEstimator', () => {
it('should throw error when no astNode available on field when using directiveEstimator', () => {
const ast = parse(`
query {
_service {
Expand All @@ -532,12 +539,13 @@ describe('QueryComplexity analysis', () => {
}
`);

const complexity = getComplexity({
estimators: [directiveEstimator()],
schema,
query: ast,
});
expect(Number.isNaN(complexity)).to.equal(true);
expect(() => {
getComplexity({
estimators: [directiveEstimator()],
schema,
query: ast,
});
}).to.throw(/No complexity could be calculated for field Query._service/);
});

it('should skip complexity calculation by directiveEstimator when no astNode available on field', () => {
Expand Down Expand Up @@ -796,4 +804,32 @@ describe('QueryComplexity analysis', () => {
});
expect(complexity).to.equal(30); // 3 fields on nonNullItem * 10
});

it('should handle invalid argument values for multiple query fields', () => {
const ast = parse(`
query {
requiredArgs(count: x) {
scalar
complexScalar
}
nonNullItem {
scalar
complexScalar
variableScalar(count: 10)
}
}
`);

validate(schema, ast, [
...specifiedRules,
createComplexityRule({
maximumComplexity: 1000,
estimators: [
simpleEstimator({
defaultComplexity: 1,
}),
],
}),
]);
});
});

0 comments on commit 7d045b1

Please sign in to comment.