diff --git a/src/graphql/execution/execute.py b/src/graphql/execution/execute.py index 58488f8f..35bddba4 100644 --- a/src/graphql/execution/execute.py +++ b/src/graphql/execution/execute.py @@ -1984,6 +1984,13 @@ async def yield_subsequent_payloads( break +UNEXPECTED_EXPERIMENTAL_DIRECTIVES = ( + "The provided schema unexpectedly contains experimental directives" + " (@defer or @stream). These directives may only be utilized" + " if experimental execution features are explicitly enabled." +) + + UNEXPECTED_MULTIPLE_PAYLOADS = ( "Executing this GraphQL operation would unexpectedly produce multiple payloads" " (due to @defer or @stream directive)" @@ -2016,10 +2023,12 @@ def execute( This function does not support incremental delivery (`@defer` and `@stream`). If an operation that defers or streams data is executed with this function, - it will throw or resolve to an object containing an error instead. - Use `experimental_execute_incrementally` if you want to support incremental - delivery. + it will throw an error instead. Use `experimental_execute_incrementally` if + you want to support incremental delivery. """ + if schema.get_directive("defer") or schema.get_directive("stream"): + raise GraphQLError(UNEXPECTED_EXPERIMENTAL_DIRECTIVES) + result = experimental_execute_incrementally( schema, document, @@ -2043,9 +2052,7 @@ async def await_result() -> Any: awaited_result = await result if isinstance(awaited_result, ExecutionResult): return awaited_result - return ExecutionResult( - None, errors=[GraphQLError(UNEXPECTED_MULTIPLE_PAYLOADS)] - ) + raise GraphQLError(UNEXPECTED_MULTIPLE_PAYLOADS) return await_result() diff --git a/tests/execution/test_defer.py b/tests/execution/test_defer.py index 866a1c13..ff17c9f0 100644 --- a/tests/execution/test_defer.py +++ b/tests/execution/test_defer.py @@ -962,15 +962,10 @@ async def original_execute_function_throws_error_if_deferred_and_not_all_is_sync """ ) - result = await execute(schema, document, {}) # type: ignore + with pytest.raises(GraphQLError) as exc_info: + await execute(schema, document, {}) # type: ignore - assert result == ( - None, - [ - { - "message": "Executing this GraphQL operation would unexpectedly" - " produce multiple payloads" - " (due to @defer or @stream directive)" - } - ], + assert str(exc_info.value) == ( + "Executing this GraphQL operation would unexpectedly produce" + " multiple payloads (due to @defer or @stream directive)" ) diff --git a/tests/execution/test_executor.py b/tests/execution/test_executor.py index 61f4ba62..fd80051b 100644 --- a/tests/execution/test_executor.py +++ b/tests/execution/test_executor.py @@ -9,6 +9,7 @@ from graphql.type import ( GraphQLArgument, GraphQLBoolean, + GraphQLDeferDirective, GraphQLField, GraphQLInt, GraphQLInterfaceType, @@ -18,6 +19,7 @@ GraphQLResolveInfo, GraphQLScalarType, GraphQLSchema, + GraphQLStreamDirective, GraphQLString, GraphQLUnionType, ResponsePath, @@ -786,6 +788,38 @@ class Data: result = execute_sync(schema, document, Data(), operation_name="S") assert result == ({"a": "b"}, None) + def errors_when_using_original_execute_with_schemas_including_experimental_defer(): + schema = GraphQLSchema( + query=GraphQLObjectType("Q", {"a": GraphQLField(GraphQLString)}), + directives=[GraphQLDeferDirective], + ) + document = parse("query Q { a }") + + with pytest.raises(GraphQLError) as exc_info: + execute(schema, document) + + assert str(exc_info.value) == ( + "The provided schema unexpectedly contains experimental directives" + " (@defer or @stream). These directives may only be utilized" + " if experimental execution features are explicitly enabled." + ) + + def errors_when_using_original_execute_with_schemas_including_experimental_stream(): + schema = GraphQLSchema( + query=GraphQLObjectType("Q", {"a": GraphQLField(GraphQLString)}), + directives=[GraphQLStreamDirective], + ) + document = parse("query Q { a }") + + with pytest.raises(GraphQLError) as exc_info: + execute(schema, document) + + assert str(exc_info.value) == ( + "The provided schema unexpectedly contains experimental directives" + " (@defer or @stream). These directives may only be utilized" + " if experimental execution features are explicitly enabled." + ) + def resolves_to_an_error_if_schema_does_not_support_operation(): schema = GraphQLSchema(assume_valid=True)