diff --git a/src/graphql/execution/values.py b/src/graphql/execution/values.py index 3080a1d7..640f9ea9 100644 --- a/src/graphql/execution/values.py +++ b/src/graphql/execution/values.py @@ -136,7 +136,7 @@ def on_input_value_error( GraphQLError( prefix + "; " + error.message, var_def_node, # noqa: B023 - original_error=error.original_error, + original_error=error, ) ) diff --git a/tests/execution/test_variables.py b/tests/execution/test_variables.py index 88cf180e..8e82ebec 100644 --- a/tests/execution/test_variables.py +++ b/tests/execution/test_variables.py @@ -1,6 +1,7 @@ from math import nan from typing import Any, Dict, Optional +from graphql.error import GraphQLError from graphql.execution import ExecutionResult, execute_sync from graphql.execution.values import get_variable_values from graphql.language import OperationDefinitionNode, StringValueNode, ValueNode, parse @@ -21,6 +22,25 @@ GraphQLString, ) +TestFaultyScalarGraphQLError = GraphQLError( + "FaultyScalarErrorMessage", extensions={"code": "FaultyScalarExtensionCode"} +) + + +def faulty_parse_value(value: str) -> str: + raise TestFaultyScalarGraphQLError + + +def faulty_parse_literal(ast: ValueNode, _variables=None) -> str: + raise TestFaultyScalarGraphQLError + + +TestFaultyScalar = GraphQLScalarType( + name="FaultyScalar", + parse_value=faulty_parse_value, + parse_literal=faulty_parse_literal, +) + def parse_serialized_value(value: str) -> str: assert value == "SerializedValue" @@ -47,6 +67,7 @@ def parse_literal_value(ast: ValueNode, _variables=None) -> str: "b": GraphQLInputField(GraphQLList(GraphQLString)), "c": GraphQLInputField(GraphQLNonNull(GraphQLString)), "d": GraphQLInputField(TestComplexScalar), + "e": GraphQLInputField(TestFaultyScalar), }, ) @@ -253,6 +274,27 @@ def properly_runs_parse_literal_on_complex_scalar_types(): None, ) + def errors_on_faulty_scalar_type_input(): + result = execute_query( + """ + { + fieldWithObjectInput(input: {c: "foo", e: "bar"}) + } + """ + ) + + assert result == ( + {"fieldWithObjectInput": None}, + [ + { + "message": "Argument 'input' has invalid value" + ' { c: "foo", e: "bar" }.', + "path": ["fieldWithObjectInput"], + "locations": [(3, 51)], + } + ], + ) + def describe_using_variables(): doc = """ query ($input: TestInputObject) { @@ -365,6 +407,22 @@ def executes_with_complex_scalar_input(): None, ) + def errors_on_faulty_scalar_type_input(): + params = {"input": {"c": "foo", "e": "SerializedValue"}} + result = execute_query(doc, params) + + assert result == ( + None, + [ + { + "message": "Variable '$input' got invalid value" + " 'SerializedValue' at 'input.e'; FaultyScalarErrorMessage", + "locations": [(2, 24)], + "extensions": {"code": "FaultyScalarExtensionCode"}, + } + ], + ) + def errors_on_null_for_nested_non_null(): params = {"input": {"a": "foo", "b": "bar", "c": None}} result = execute_query(doc, params) @@ -676,8 +734,8 @@ def reports_error_for_array_passed_into_string_input(): ) errors = result.errors - assert errors is not None - assert errors[0].original_error is None + assert errors + assert errors[0].original_error def reports_error_for_non_provided_variables_for_non_nullable_inputs(): # Note: this test would typically fail validation before