Skip to content

Commit

Permalink
Original execute should throw if defer/stream directives are present
Browse files Browse the repository at this point in the history
  • Loading branch information
Cito committed Apr 5, 2024
1 parent ae91327 commit 891586d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 16 deletions.
19 changes: 13 additions & 6 deletions src/graphql/execution/execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)"
Expand Down Expand Up @@ -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,
Expand All @@ -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()

Expand Down
15 changes: 5 additions & 10 deletions tests/execution/test_defer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)"
)
34 changes: 34 additions & 0 deletions tests/execution/test_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from graphql.type import (
GraphQLArgument,
GraphQLBoolean,
GraphQLDeferDirective,
GraphQLField,
GraphQLInt,
GraphQLInterfaceType,
Expand All @@ -18,6 +19,7 @@
GraphQLResolveInfo,
GraphQLScalarType,
GraphQLSchema,
GraphQLStreamDirective,
GraphQLString,
GraphQLUnionType,
ResponsePath,
Expand Down Expand Up @@ -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)

Expand Down

0 comments on commit 891586d

Please sign in to comment.