Skip to content

Commit cf64958

Browse files
committed
Standardize error messages prior to introducing schema coordinates
Replicates graphql/graphql-js@3fdae36f
1 parent 20183e1 commit cf64958

20 files changed

Lines changed: 237 additions & 212 deletions

src/graphql/execution/execute.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,7 @@ def complete_value(
790790
if isinstance(completed, GraphQLWrappedResult) and completed.result is None:
791791
msg = (
792792
"Cannot return null for non-nullable field"
793-
f" {info.parent_type.name}.{info.field_name}."
793+
f" {info.parent_type}.{info.field_name}."
794794
)
795795
raise TypeError(msg)
796796
return completed
@@ -1087,7 +1087,7 @@ def complete_list_value(
10871087
if not is_iterable(result):
10881088
msg = (
10891089
"Expected Iterable, but did not find one for field"
1090-
f" '{info.parent_type.name}.{info.field_name}'."
1090+
f" '{info.parent_type}.{info.field_name}'."
10911091
)
10921092
raise GraphQLError(msg)
10931093

@@ -1392,10 +1392,10 @@ def ensure_valid_runtime_type(
13921392
"""Ensure that the given type is valid at runtime."""
13931393
if runtime_type_name is None:
13941394
msg = (
1395-
f"Abstract type '{return_type.name}' must resolve"
1395+
f"Abstract type '{return_type}' must resolve"
13961396
" to an Object type at runtime"
1397-
f" for field '{info.parent_type.name}.{info.field_name}'."
1398-
f" Either the '{return_type.name}' type should provide"
1397+
f" for field '{info.parent_type}.{info.field_name}'."
1398+
f" Either the '{return_type}' type should provide"
13991399
" a 'resolve_type' function or each possible type should provide"
14001400
" an 'is_type_of' function."
14011401
)
@@ -1410,9 +1410,9 @@ def ensure_valid_runtime_type(
14101410

14111411
if not isinstance(runtime_type_name, str):
14121412
msg = (
1413-
f"Abstract type '{return_type.name}' must resolve"
1413+
f"Abstract type '{return_type}' must resolve"
14141414
" to an Object type at runtime"
1415-
f" for field '{info.parent_type.name}.{info.field_name}' with value"
1415+
f" for field '{info.parent_type}.{info.field_name}' with value"
14161416
f" {inspect(result)}, received '{inspect(runtime_type_name)}'."
14171417
)
14181418
raise GraphQLError(msg, to_nodes(field_group))
@@ -1421,22 +1421,22 @@ def ensure_valid_runtime_type(
14211421

14221422
if runtime_type is None:
14231423
msg = (
1424-
f"Abstract type '{return_type.name}' was resolved to a type"
1424+
f"Abstract type '{return_type}' was resolved to a type"
14251425
f" '{runtime_type_name}' that does not exist inside the schema."
14261426
)
14271427
raise GraphQLError(msg, to_nodes(field_group))
14281428

14291429
if not is_object_type(runtime_type):
14301430
msg = (
1431-
f"Abstract type '{return_type.name}' was resolved"
1431+
f"Abstract type '{return_type}' was resolved"
14321432
f" to a non-object type '{runtime_type_name}'."
14331433
)
14341434
raise GraphQLError(msg, to_nodes(field_group))
14351435

14361436
if not self.schema.is_sub_type(return_type, runtime_type):
14371437
msg = (
1438-
f"Runtime Object type '{runtime_type.name}' is not a possible"
1439-
f" type for '{return_type.name}'."
1438+
f"Runtime Object type '{runtime_type}' is not a possible"
1439+
f" type for '{return_type}'."
14401440
)
14411441
raise GraphQLError(msg, to_nodes(field_group))
14421442

@@ -2288,7 +2288,7 @@ def invalid_return_type_error(
22882288
) -> GraphQLError:
22892289
"""Create a GraphQLError for an invalid return type."""
22902290
return GraphQLError(
2291-
f"Expected value of type '{return_type.name}' but got: {inspect(result)}.",
2291+
f"Expected value of type '{return_type}' but got: {inspect(result)}.",
22922292
to_nodes(field_group),
22932293
)
22942294

src/graphql/execution/values.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,10 @@ def get_argument_values(
215215
# Note: `values_of_correct_type` validation should catch this before
216216
# execution. This is a runtime check to ensure execution does not
217217
# continue with an invalid argument value.
218-
msg = f"Argument '{name}' has invalid value {print_ast(value_node)}."
218+
msg = (
219+
f"Argument '{name}' of type '{inspect(arg_type)}'"
220+
f" has invalid value {print_ast(value_node)}."
221+
)
219222
raise GraphQLError(msg, value_node)
220223
coerced_values[arg_def.out_name or name] = coerced_value
221224

src/graphql/type/validate.py

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ def validate_root_types(self) -> None:
136136
)
137137
self.report_error(
138138
"All root types must be different,"
139-
f" '{root_type.name}' type is used as {operation_list} root types.",
139+
f" '{root_type}' type is used as {operation_list} root types.",
140140
[
141141
get_operation_type_node(schema, operation_type)
142142
for operation_type in operation_types
@@ -159,7 +159,7 @@ def validate_directives(self) -> None:
159159

160160
if not directive.locations:
161161
self.report_error(
162-
f"Directive @{directive.name} must include 1 or more locations.",
162+
f"Directive {directive} must include 1 or more locations.",
163163
directive.ast_node,
164164
)
165165

@@ -171,14 +171,14 @@ def validate_directives(self) -> None:
171171
# Ensure the type is an input type.
172172
if not is_input_type(arg.type):
173173
self.report_error(
174-
f"The type of @{directive.name}({arg_name}:)"
174+
f"The type of {directive}({arg_name}:)"
175175
f" must be Input Type but got: {inspect(arg.type)}.",
176176
arg.ast_node,
177177
)
178178

179179
if is_required_argument(arg) and arg.deprecation_reason is not None:
180180
self.report_error(
181-
f"Required argument @{directive.name}({arg_name}:)"
181+
f"Required argument {directive}({arg_name}:)"
182182
" cannot be deprecated.",
183183
[
184184
get_deprecated_directive_node(arg.ast_node),
@@ -249,7 +249,7 @@ def validate_fields(self, type_: GraphQLObjectType | GraphQLInterfaceType) -> No
249249
# Objects and Interfaces both must define one or more fields.
250250
if not fields:
251251
self.report_error(
252-
f"Type {type_.name} must define one or more fields.",
252+
f"Type {type_} must define one or more fields.",
253253
[type_.ast_node, *type_.extension_ast_nodes],
254254
)
255255

@@ -260,7 +260,7 @@ def validate_fields(self, type_: GraphQLObjectType | GraphQLInterfaceType) -> No
260260
# Ensure the type is an output type
261261
if not is_output_type(field.type):
262262
self.report_error(
263-
f"The type of {type_.name}.{field_name}"
263+
f"The type of {type_}.{field_name}"
264264
f" must be Output Type but got: {inspect(field.type)}.",
265265
field.ast_node and field.ast_node.type,
266266
)
@@ -273,14 +273,14 @@ def validate_fields(self, type_: GraphQLObjectType | GraphQLInterfaceType) -> No
273273
# Ensure the type is an input type.
274274
if not is_input_type(arg.type):
275275
self.report_error(
276-
f"The type of {type_.name}.{field_name}({arg_name}:)"
276+
f"The type of {type_}.{field_name}({arg_name}:)"
277277
f" must be Input Type but got: {inspect(arg.type)}.",
278278
arg.ast_node and arg.ast_node.type,
279279
)
280280

281281
if is_required_argument(arg) and arg.deprecation_reason is not None:
282282
self.report_error(
283-
f"Required argument {type_.name}.{field_name}({arg_name}:)"
283+
f"Required argument {type_}.{field_name}({arg_name}:)"
284284
" cannot be deprecated.",
285285
[
286286
get_deprecated_directive_node(arg.ast_node),
@@ -303,14 +303,14 @@ def validate_interfaces(
303303

304304
if type_ is iface:
305305
self.report_error(
306-
f"Type {type_.name} cannot implement itself"
306+
f"Type {type_} cannot implement itself"
307307
" because it would create a circular reference.",
308308
get_all_implements_interface_nodes(type_, iface),
309309
)
310310

311311
if iface.name in iface_type_names:
312312
self.report_error(
313-
f"Type {type_.name} can only implement {iface.name} once.",
313+
f"Type {type_} can only implement {iface.name} once.",
314314
get_all_implements_interface_nodes(type_, iface),
315315
)
316316
continue
@@ -335,7 +335,7 @@ def validate_type_implements_interface(
335335
if not type_field:
336336
self.report_error(
337337
f"Interface field {iface.name}.{field_name}"
338-
f" expected but {type_.name} does not provide it.",
338+
f" expected but {type_} does not provide it.",
339339
[
340340
iface_field.ast_node,
341341
type_.ast_node,
@@ -350,7 +350,7 @@ def validate_type_implements_interface(
350350
self.report_error(
351351
f"Interface field {iface.name}.{field_name}"
352352
f" expects type {iface_field.type}"
353-
f" but {type_.name}.{field_name}"
353+
f" but {type_}.{field_name}"
354354
f" is type {type_field.type}.",
355355
[
356356
iface_field.ast_node and iface_field.ast_node.type,
@@ -367,7 +367,7 @@ def validate_type_implements_interface(
367367
self.report_error(
368368
"Interface field argument"
369369
f" {iface.name}.{field_name}({arg_name}:)"
370-
f" expected but {type_.name}.{field_name}"
370+
f" expected but {type_}.{field_name}"
371371
" does not provide it.",
372372
[iface_arg.ast_node, type_field.ast_node],
373373
)
@@ -380,7 +380,7 @@ def validate_type_implements_interface(
380380
"Interface field argument"
381381
f" {iface.name}.{field_name}({arg_name}:)"
382382
f" expects type {iface_arg.type}"
383-
f" but {type_.name}.{field_name}({arg_name}:)"
383+
f" but {type_}.{field_name}({arg_name}:)"
384384
f" is type {type_arg.type}.",
385385
[
386386
iface_arg.ast_node and iface_arg.ast_node.type,
@@ -393,9 +393,9 @@ def validate_type_implements_interface(
393393
iface_arg = iface_field.args.get(arg_name)
394394
if not iface_arg and is_required_argument(type_arg):
395395
self.report_error(
396-
f"Object field {type_.name}.{field_name} includes"
397-
f" required argument {arg_name} that is missing from"
398-
f" the Interface field {iface.name}.{field_name}.",
396+
f"Argument '{type_}.{field_name}({arg_name}:)' must not be"
397+
f" required type '{inspect(type_arg.type)}' if not provided"
398+
f" by the Interface field '{iface.name}.{field_name}'.",
399399
[type_arg.ast_node, iface_field.ast_node],
400400
)
401401

@@ -408,10 +408,10 @@ def validate_type_implements_ancestors(
408408
for transitive in iface_interfaces:
409409
if transitive not in type_interfaces:
410410
self.report_error(
411-
f"Type {type_.name} cannot implement {iface.name}"
411+
f"Type {type_} cannot implement {iface.name}"
412412
" because it would create a circular reference."
413413
if transitive is type_
414-
else f"Type {type_.name} must implement {transitive.name}"
414+
else f"Type {type_} must implement {transitive.name}"
415415
f" because it is implemented by {iface.name}.",
416416
get_all_implements_interface_nodes(iface, transitive)
417417
+ get_all_implements_interface_nodes(type_, iface),
@@ -432,7 +432,7 @@ def validate_union_members(self, union: GraphQLUnionType) -> None:
432432
if member_type.name in included_type_names:
433433
self.report_error(
434434
f"Union type {union.name} can only include type"
435-
f" {member_type.name} once.",
435+
f" {member_type} once.",
436436
get_union_member_type_nodes(union, member_type.name),
437437
)
438438
else:
@@ -449,7 +449,7 @@ def validate_enum_values(self, enum_type: GraphQLEnumType) -> None:
449449

450450
if not enum_values:
451451
self.report_error(
452-
f"Enum type {enum_type.name} must define one or more values.",
452+
f"Enum type {enum_type} must define one or more values.",
453453
[enum_type.ast_node, *enum_type.extension_ast_nodes],
454454
)
455455

@@ -500,14 +500,13 @@ def validate_one_of_input_object_field(
500500
) -> None:
501501
if is_non_null_type(field.type):
502502
self.report_error(
503-
f"OneOf input field {type_.name}.{field_name} must be nullable.",
503+
f"OneOf input field {type_}.{field_name} must be nullable.",
504504
field.ast_node and field.ast_node.type,
505505
)
506506

507507
if field.default_value is not Undefined:
508508
self.report_error(
509-
f"OneOf input field {type_.name}.{field_name}"
510-
" cannot have a default value.",
509+
f"OneOf input field {type_}.{field_name} cannot have a default value.",
511510
field.ast_node,
512511
)
513512

@@ -565,7 +564,7 @@ def __call__(self, input_obj: GraphQLInputObjectType) -> None:
565564
cycle_path = self.field_path[cycle_index:]
566565
field_names = map(itemgetter(0), cycle_path)
567566
self.context.report_error(
568-
f"Cannot reference Input Object '{field_type.name}'"
567+
f"Cannot reference Input Object '{field_type}'"
569568
" within itself through a series of non-null fields:"
570569
f" '{'.'.join(field_names)}'.",
571570
cast(

src/graphql/utilities/coerce_input_value.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def coerce_input_value(
8383
on_error(
8484
path.as_list() if path else [],
8585
input_value,
86-
GraphQLError(f"Expected type '{type_.name}' to be a mapping."),
86+
GraphQLError(f"Expected type '{type_}' to be a mapping."),
8787
)
8888
return Undefined
8989

@@ -103,8 +103,8 @@ def coerce_input_value(
103103
path.as_list() if path else [],
104104
input_value,
105105
GraphQLError(
106-
f"Field '{field_name}' of required type '{type_str}'"
107-
" was not provided."
106+
f"Field '{type_}.{field_name}' of required type"
107+
f" '{type_str}' was not provided."
108108
),
109109
)
110110
continue
@@ -121,7 +121,7 @@ def coerce_input_value(
121121
path.as_list() if path else [],
122122
input_value,
123123
GraphQLError(
124-
f"Field '{field_name}' is not defined by type '{type_.name}'."
124+
f"Field '{field_name}' is not defined by type '{type_}'."
125125
+ did_you_mean(suggestions)
126126
),
127127
)
@@ -133,8 +133,7 @@ def coerce_input_value(
133133
path.as_list() if path else [],
134134
input_value,
135135
GraphQLError(
136-
"Exactly one key must be specified"
137-
f" for OneOf type '{type_.name}'.",
136+
f"Exactly one key must be specified for OneOf type '{type_}'.",
138137
),
139138
)
140139
else:
@@ -165,16 +164,14 @@ def coerce_input_value(
165164
on_error(
166165
path.as_list() if path else [],
167166
input_value,
168-
GraphQLError(
169-
f"Expected type '{type_.name}'. {error}", original_error=error
170-
),
167+
GraphQLError(f"Expected type '{type_}'. {error}", original_error=error),
171168
)
172169
return Undefined
173170
if parse_result is Undefined:
174171
on_error(
175172
path.as_list() if path else [],
176173
input_value,
177-
GraphQLError(f"Expected type '{type_.name}'."),
174+
GraphQLError(f"Expected type '{type_}'."),
178175
)
179176
return parse_result
180177

0 commit comments

Comments
 (0)