Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7d045b1

Browse files
committed
Add handling for invalid argument values, error reporting in getComplexity function #61
1 parent a940f94 commit 7d045b1

File tree

4 files changed

+71
-21
lines changed

4 files changed

+71
-21
lines changed

‎.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
node_modules
33
.DS_Store
44
.idea
5+
.vscode

‎README.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -171,16 +171,21 @@ const query = parse(`
171171
}
172172
`);
173173

174-
const complexity = getComplexity({
175-
estimators: [simpleEstimator({ defaultComplexity: 1 })],
176-
schema,
177-
query,
178-
variables: {
179-
count: 10,
180-
},
181-
});
182-
183-
console.log(complexity); // Output: 3
174+
try {
175+
const complexity = getComplexity({
176+
estimators: [simpleEstimator({ defaultComplexity: 1 })],
177+
schema,
178+
query,
179+
variables: {
180+
count: 10,
181+
},
182+
});
183+
184+
console.log(complexity); // Output: 3
185+
} catch (e) {
186+
// Log error in case complexity cannot be calculated (invalid query, misconfiguration, etc.)
187+
console.error('Could not calculate complexity', e.message);
188+
}
184189
```
185190

186191
## Prior Art

‎src/QueryComplexity.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,12 @@ export function getComplexity(options: {
9696
}): number {
9797
const typeInfo = new TypeInfo(options.schema);
9898

99+
const errors: GraphQLError[] = [];
99100
const context = new ValidationContext(
100101
options.schema,
101102
options.query,
102103
typeInfo,
103-
() => null
104+
(error) => errors.push(error)
104105
);
105106
const visitor = new QueryComplexity(context, {
106107
// Maximum complexity does not matter since we're only interested in the calculated complexity.
@@ -111,6 +112,12 @@ export function getComplexity(options: {
111112
});
112113

113114
visit(options.query, visitWithTypeInfo(typeInfo, visitor));
115+
116+
// Throw first error if any
117+
if (errors.length) {
118+
throw errors.pop();
119+
}
120+
114121
return visitor.complexity;
115122
}
116123

@@ -244,7 +251,7 @@ export default class QueryComplexity {
244251
(
245252
complexities: ComplexityMap,
246253
childNode: FieldNode | FragmentSpreadNode | InlineFragmentNode
247-
) => {
254+
): ComplexityMap => {
248255
// let nodeComplexity = 0;
249256
let innerComplexities = complexities;
250257

@@ -297,7 +304,8 @@ export default class QueryComplexity {
297304
this.variableValues || {}
298305
);
299306
} catch (e) {
300-
return this.context.reportError(e);
307+
this.context.reportError(e);
308+
return complexities;
301309
}
302310

303311
// Check if we have child complexity

‎src/__tests__/QueryComplexity-test.ts

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22
* Created by Ivo Meißner on 28.07.17.
33
*/
44

5-
import { parse, TypeInfo, visit, visitWithTypeInfo } from 'graphql';
5+
import {
6+
parse,
7+
TypeInfo,
8+
visit,
9+
visitWithTypeInfo,
10+
validate,
11+
specifiedRules,
12+
} from 'graphql';
613

714
import { expect } from 'chai';
815

@@ -523,7 +530,7 @@ describe('QueryComplexity analysis', () => {
523530
);
524531
});
525532

526-
it('should return NaN when no astNode available on field when using directiveEstimator', () => {
533+
it('should throw error when no astNode available on field when using directiveEstimator', () => {
527534
const ast = parse(`
528535
query {
529536
_service {
@@ -532,12 +539,13 @@ describe('QueryComplexity analysis', () => {
532539
}
533540
`);
534541

535-
const complexity = getComplexity({
536-
estimators: [directiveEstimator()],
537-
schema,
538-
query: ast,
539-
});
540-
expect(Number.isNaN(complexity)).to.equal(true);
542+
expect(() => {
543+
getComplexity({
544+
estimators: [directiveEstimator()],
545+
schema,
546+
query: ast,
547+
});
548+
}).to.throw(/NocomplexitycouldbecalculatedforfieldQuery._service/);
541549
});
542550

543551
it('should skip complexity calculation by directiveEstimator when no astNode available on field', () => {
@@ -796,4 +804,32 @@ describe('QueryComplexity analysis', () => {
796804
});
797805
expect(complexity).to.equal(30); // 3 fields on nonNullItem * 10
798806
});
807+
808+
it('should handle invalid argument values for multiple query fields', () => {
809+
const ast = parse(`
810+
query {
811+
requiredArgs(count: x) {
812+
scalar
813+
complexScalar
814+
}
815+
nonNullItem {
816+
scalar
817+
complexScalar
818+
variableScalar(count: 10)
819+
}
820+
}
821+
`);
822+
823+
validate(schema, ast, [
824+
...specifiedRules,
825+
createComplexityRule({
826+
maximumComplexity: 1000,
827+
estimators: [
828+
simpleEstimator({
829+
defaultComplexity: 1,
830+
}),
831+
],
832+
}),
833+
]);
834+
});
799835
});

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /