Skip to content

Commit 31171e1

Browse files
committed
fix: name fragment variables as such in execution errors
Replicates graphql/graphql-js@6ce253d
1 parent 4798831 commit 31171e1

2 files changed

Lines changed: 36 additions & 13 deletions

File tree

src/graphql/execution/values.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ def coerce_argument(
270270
# before execution. This is a runtime check to ensure execution does
271271
# not continue with an invalid argument value.
272272
msg = (
273-
f"Argument '{arg_name}' of required type '{arg_type}' was not provided."
273+
f"{print_argument_or_fragment_variable(arg_def, arg_name, node)}"
274+
f" of required type '{arg_type}' was not provided."
274275
)
275276
raise GraphQLError(msg, node)
276277
coerced_default_value = coerce_default_value(arg_def)
@@ -312,11 +313,10 @@ def coerce_argument(
312313
def on_argument_value_error(
313314
error: GraphQLError,
314315
path: list[str | int],
315-
arg_name: str = arg_name,
316316
) -> None:
317317
error.message = (
318-
f"Argument '{arg_name}' has invalid value"
319-
f"{print_path_list(path)}: {error.message}"
318+
f"{print_argument_or_fragment_variable(arg_def, arg_name, node)}"
319+
f" has invalid value{print_path_list(path)}: {error.message}"
320320
)
321321
raise error
322322

@@ -334,6 +334,19 @@ def on_argument_value_error(
334334
coerced_values[out_name] = coerced_value
335335

336336

337+
# TODO: clean up the naming of is_required_argument() and arg_def
338+
# if/when experimental fragment variables are merged
339+
def print_argument_or_fragment_variable(
340+
arg_def: GraphQLArgument | GraphQLVariableSignature,
341+
arg_name: str,
342+
node: FieldNode | DirectiveNode | FragmentSpreadNode,
343+
) -> str:
344+
"""Describe an argument or fragment variable for use in error messages."""
345+
if isinstance(arg_def, GraphQLVariableSignature):
346+
return f"Variable '${arg_def.name}' defined by fragment '{node.name.value}'"
347+
return f"Argument '{arg_name}'"
348+
349+
337350
NodeWithDirective: TypeAlias = (
338351
EnumValueDefinitionNode
339352
| ExecutableDefinitionNode

tests/execution/test_variables.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,10 +1189,15 @@ def when_a_value_is_required_and_not_provided():
11891189
}
11901190
"""
11911191
)
1192-
assert result.errors is not None
1193-
assert len(result.errors) == 1
1194-
assert result.errors[0].message.startswith(
1195-
"Argument 'value' of required type 'String!'"
1192+
assert result == (
1193+
None,
1194+
[
1195+
{
1196+
"message": "Variable '$value' defined by fragment 'a'"
1197+
" of required type 'String!' was not provided.",
1198+
"locations": [(3, 19)],
1199+
}
1200+
],
11961201
)
11971202

11981203
def when_the_definition_has_a_default_and_is_provided():
@@ -1257,11 +1262,16 @@ def when_the_definition_has_a_non_nullable_default_and_is_provided_null():
12571262
}
12581263
"""
12591264
)
1260-
assert result.errors is not None
1261-
assert len(result.errors) == 1
1262-
assert result.errors[0].message.startswith(
1263-
"Argument 'value' has invalid value:"
1264-
" Expected value of non-null type 'String!' not to be None."
1265+
assert result == (
1266+
None,
1267+
[
1268+
{
1269+
"message": "Variable '$value' defined by fragment 'a'"
1270+
" has invalid value: Expected value of non-null type"
1271+
" 'String!' not to be None.",
1272+
"locations": [(3, 31)],
1273+
}
1274+
],
12651275
)
12661276

12671277
def when_the_definition_has_no_default_and_is_not_provided():

0 commit comments

Comments
 (0)