Skip to content

Commit 79ad146

Browse files
introduce GraphQLField, GraphQLInputField, GraphQLArgument, and GraphQLEnumValue (#4288)
this extracts logic from #3044 and #3145 (later rebased as #3807 and #3808) to implement more informative error messages without implementing [the full schema coordinate RFC](graphql/graphql-spec#794) This is a BREAKING CHANGE because these schema elements are now longer plain objects and function differently in various scenarios, for example with `String(<schemaElement>` `JSON.stringifu(<schemaElement>` and `.toString()` and `.toJSON()` --------- Co-authored-by: Jovi De Croock <[email protected]>
1 parent 57ba3a3 commit 79ad146

22 files changed

+767
-540
lines changed

src/execution/__tests__/nonnull-test.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ describe('Execute: handles non-nullable types', () => {
683683
errors: [
684684
{
685685
message:
686-
'Argument "cannotBeNull" of required type "String!" was not provided.',
686+
'Argument "Query.withNonNullArg(cannotBeNull:)" of required type "String!" was not provided.',
687687
locations: [{ line: 3, column: 13 }],
688688
path: ['withNonNullArg'],
689689
},
@@ -710,7 +710,7 @@ describe('Execute: handles non-nullable types', () => {
710710
errors: [
711711
{
712712
message:
713-
'Argument "cannotBeNull" has invalid value: Expected value of non-null type "String!" not to be null.',
713+
'Argument "Query.withNonNullArg(cannotBeNull:)" has invalid value: Expected value of non-null type "String!" not to be null.',
714714
locations: [{ line: 3, column: 42 }],
715715
path: ['withNonNullArg'],
716716
},
@@ -740,7 +740,7 @@ describe('Execute: handles non-nullable types', () => {
740740
errors: [
741741
{
742742
message:
743-
'Argument "cannotBeNull" has invalid value: Expected variable "$testVar" provided to type "String!" to provide a runtime value.',
743+
'Argument "Query.withNonNullArg(cannotBeNull:)" has invalid value: Expected variable "$testVar" provided to type "String!" to provide a runtime value.',
744744
locations: [{ line: 3, column: 42 }],
745745
path: ['withNonNullArg'],
746746
},
@@ -768,7 +768,7 @@ describe('Execute: handles non-nullable types', () => {
768768
errors: [
769769
{
770770
message:
771-
'Argument "cannotBeNull" has invalid value: Expected variable "$testVar" provided to non-null type "String!" not to be null.',
771+
'Argument "Query.withNonNullArg(cannotBeNull:)" has invalid value: Expected variable "$testVar" provided to non-null type "String!" not to be null.',
772772
locations: [{ line: 3, column: 43 }],
773773
path: ['withNonNullArg'],
774774
},

src/execution/__tests__/oneof-test.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ describe('Execute: Handles OneOf Input Objects', () => {
8888
message:
8989
// This type of error would be caught at validation-time
9090
// hence the vague error message here.
91-
'Argument "input" has invalid value: Expected variable "$input" provided to type "TestInputObject!" to provide a runtime value.',
91+
'Argument "Query.test(input:)" has invalid value: Expected variable "$input" provided to type "TestInputObject!" to provide a runtime value.',
9292
path: ['test'],
9393
},
9494
],
@@ -229,7 +229,7 @@ describe('Execute: Handles OneOf Input Objects', () => {
229229
// A nullable variable in a oneOf field position would be caught at validation-time
230230
// hence the vague error message here.
231231
message:
232-
'Argument "input" has invalid value: Expected variable "$a" provided to field "a" for OneOf Input Object type "TestInputObject" not to be null.',
232+
'Argument "Query.test(input:)" has invalid value: Expected variable "$a" provided to field "a" for OneOf Input Object type "TestInputObject" not to be null.',
233233
locations: [{ line: 3, column: 23 }],
234234
path: ['test'],
235235
},
@@ -257,7 +257,7 @@ describe('Execute: Handles OneOf Input Objects', () => {
257257
// A nullable variable in a oneOf field position would be caught at validation-time
258258
// hence the vague error message here.
259259
message:
260-
'Argument "input" has invalid value: Expected variable "$a" provided to field "a" for OneOf Input Object type "TestInputObject" to provide a runtime value.',
260+
'Argument "Query.test(input:)" has invalid value: Expected variable "$a" provided to field "a" for OneOf Input Object type "TestInputObject" to provide a runtime value.',
261261
locations: [{ line: 3, column: 23 }],
262262
path: ['test'],
263263
},
@@ -288,7 +288,7 @@ describe('Execute: Handles OneOf Input Objects', () => {
288288
// A nullable variable in a oneOf field position would be caught at validation-time
289289
// hence the vague error message here.
290290
message:
291-
'Argument "input" has invalid value: Expected variable "$a" provided to field "a" for OneOf Input Object type "TestInputObject" not to be null.',
291+
'Argument "Query.test(input:)" has invalid value: Expected variable "$a" provided to field "a" for OneOf Input Object type "TestInputObject" not to be null.',
292292
locations: [{ line: 6, column: 23 }],
293293
path: ['test'],
294294
},
@@ -319,7 +319,7 @@ describe('Execute: Handles OneOf Input Objects', () => {
319319
// A nullable variable in a oneOf field position would be caught at validation-time
320320
// hence the vague error message here.
321321
message:
322-
'Argument "input" has invalid value: Expected variable "$a" provided to field "a" for OneOf Input Object type "TestInputObject" to provide a runtime value.',
322+
'Argument "Query.test(input:)" has invalid value: Expected variable "$a" provided to field "a" for OneOf Input Object type "TestInputObject" to provide a runtime value.',
323323
locations: [{ line: 6, column: 23 }],
324324
path: ['test'],
325325
},

src/execution/__tests__/variables-test.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ describe('Execute: Handles inputs', () => {
284284
errors: [
285285
{
286286
message:
287-
'Argument "input" has invalid value: Expected value of type "TestInputObject" to be an object, found: ["foo", "bar", "baz"].',
287+
'Argument "TestType.fieldWithObjectInput(input:)" has invalid value: Expected value of type "TestInputObject" to be an object, found: ["foo", "bar", "baz"].',
288288
path: ['fieldWithObjectInput'],
289289
locations: [{ line: 3, column: 41 }],
290290
},
@@ -320,7 +320,7 @@ describe('Execute: Handles inputs', () => {
320320
errors: [
321321
{
322322
message:
323-
'Argument "input" has invalid value at .e: FaultyScalarErrorMessage',
323+
'Argument "TestType.fieldWithObjectInput(input:)" has invalid value at .e: FaultyScalarErrorMessage',
324324
path: ['fieldWithObjectInput'],
325325
locations: [{ line: 3, column: 13 }],
326326
extensions: { code: 'FaultyScalarErrorExtensionCode' },
@@ -477,7 +477,7 @@ describe('Execute: Handles inputs', () => {
477477
errors: [
478478
{
479479
message:
480-
'Variable "$input" has invalid value at .e: Argument "input" has invalid value at .e: FaultyScalarErrorMessage',
480+
'Variable "$input" has invalid value at .e: Argument "TestType.fieldWithObjectInput(input:)" has invalid value at .e: FaultyScalarErrorMessage',
481481
locations: [{ line: 2, column: 16 }],
482482
extensions: { code: 'FaultyScalarErrorExtensionCode' },
483483
},
@@ -802,7 +802,7 @@ describe('Execute: Handles inputs', () => {
802802
errors: [
803803
{
804804
message:
805-
'Argument "input" of required type "String!" was not provided.',
805+
'Argument "TestType.fieldWithNonNullableStringInput(input:)" of required type "String!" was not provided.',
806806
locations: [{ line: 1, column: 3 }],
807807
path: ['fieldWithNonNullableStringInput'],
808808
},
@@ -850,7 +850,7 @@ describe('Execute: Handles inputs', () => {
850850
errors: [
851851
{
852852
message:
853-
'Argument "input" has invalid value: Expected variable "$foo" provided to type "String!" to provide a runtime value.',
853+
'Argument "TestType.fieldWithNonNullableStringInput(input:)" has invalid value: Expected variable "$foo" provided to type "String!" to provide a runtime value.',
854854
locations: [{ line: 3, column: 50 }],
855855
path: ['fieldWithNonNullableStringInput'],
856856
},
@@ -1102,7 +1102,7 @@ describe('Execute: Handles inputs', () => {
11021102
errors: [
11031103
{
11041104
message:
1105-
'Argument "input" has invalid value: String cannot represent a non string value: WRONG_TYPE',
1105+
'Argument "TestType.fieldWithDefaultArgumentValue(input:)" has invalid value: String cannot represent a non string value: WRONG_TYPE',
11061106
locations: [{ line: 3, column: 48 }],
11071107
path: ['fieldWithDefaultArgumentValue'],
11081108
},

src/execution/values.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ import type {
1414
import { Kind } from '../language/kinds.js';
1515

1616
import type { GraphQLArgument, GraphQLField } from '../type/definition.js';
17-
import { isNonNullType, isRequiredArgument } from '../type/definition.js';
17+
import {
18+
isArgument,
19+
isNonNullType,
20+
isRequiredArgument,
21+
} from '../type/definition.js';
1822
import type { GraphQLDirective } from '../type/directives.js';
1923
import type { GraphQLSchema } from '../type/schema.js';
2024

@@ -222,7 +226,8 @@ export function experimentalGetArgumentValues(
222226
// execution. This is a runtime check to ensure execution does not
223227
// continue with an invalid argument value.
224228
throw new GraphQLError(
225-
`Argument "${argDef.name}" of required type "${argType}" was not provided.`,
229+
// TODO: clean up the naming of isRequiredArgument(), isArgument(), and argDef if/when experimental fragment variables are merged
230+
`Argument "${isArgument(argDef) ? argDef : argDef.name}" of required type "${argType}" was not provided.`,
226231
{ nodes: node },
227232
);
228233
}
@@ -272,7 +277,8 @@ export function experimentalGetArgumentValues(
272277
valueNode,
273278
argType,
274279
(error, path) => {
275-
error.message = `Argument "${argDef.name}" has invalid value${printPathArray(
280+
// TODO: clean up the naming of isRequiredArgument(), isArgument(), and argDef if/when experimental fragment variables are merged
281+
error.message = `Argument "${isArgument(argDef) ? argDef : argDef.name}" has invalid value${printPathArray(
276282
path,
277283
)}: ${error.message}`;
278284
throw error;

src/index.ts

+14-4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ export type { GraphQLArgs } from './graphql.js';
3434
export { graphql, graphqlSync } from './graphql.js';
3535

3636
// Create and operate on GraphQL type definitions and schema.
37+
export type {
38+
GraphQLField,
39+
GraphQLArgument,
40+
GraphQLEnumValue,
41+
GraphQLInputField,
42+
} from './type/index.js';
3743
export {
3844
resolveObjMapThunk,
3945
resolveReadonlyArrayThunk,
@@ -91,10 +97,14 @@ export {
9197
isType,
9298
isScalarType,
9399
isObjectType,
100+
isField,
101+
isArgument,
94102
isInterfaceType,
95103
isUnionType,
96104
isEnumType,
105+
isEnumValue,
97106
isInputObjectType,
107+
isInputField,
98108
isListType,
99109
isNonNullType,
100110
isInputType,
@@ -116,10 +126,14 @@ export {
116126
assertType,
117127
assertScalarType,
118128
assertObjectType,
129+
assertField,
130+
assertArgument,
119131
assertInterfaceType,
120132
assertUnionType,
121133
assertEnumType,
134+
assertEnumValue,
122135
assertInputObjectType,
136+
assertInputField,
123137
assertListType,
124138
assertNonNullType,
125139
assertInputType,
@@ -161,23 +175,19 @@ export type {
161175
GraphQLSchemaExtensions,
162176
GraphQLDirectiveConfig,
163177
GraphQLDirectiveExtensions,
164-
GraphQLArgument,
165178
GraphQLArgumentConfig,
166179
GraphQLArgumentExtensions,
167180
GraphQLEnumTypeConfig,
168181
GraphQLEnumTypeExtensions,
169-
GraphQLEnumValue,
170182
GraphQLEnumValueConfig,
171183
GraphQLEnumValueConfigMap,
172184
GraphQLEnumValueExtensions,
173-
GraphQLField,
174185
GraphQLFieldConfig,
175186
GraphQLFieldConfigArgumentMap,
176187
GraphQLFieldConfigMap,
177188
GraphQLFieldExtensions,
178189
GraphQLFieldMap,
179190
GraphQLFieldResolver,
180-
GraphQLInputField,
181191
GraphQLInputFieldConfig,
182192
GraphQLInputFieldConfigMap,
183193
GraphQLInputFieldExtensions,

0 commit comments

Comments
 (0)