Skip to content

Commit

Permalink
Fix bug with errors thrown in the on_parse_* extension hooks (#1324)
Browse files Browse the repository at this point in the history
Before they would have been swallowed and just returned in the results
object. This change means that they get propagated up as you would
expect.
  • Loading branch information
jkimbo authored Oct 11, 2021
1 parent 19f79ec commit d79aa61
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 38 deletions.
4 changes: 4 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Release type: patch

Fix bug where errors thrown in the on_parse_* extension hooks were being
swallowed instead of being propagated.
76 changes: 38 additions & 38 deletions strawberry/schema/execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,27 +66,27 @@ async def execute(
# Note: In graphql-core the schema would be validated here but in
# Strawberry we are validating it at initialisation time instead

try:
async with extensions_runner.parsing():
async with extensions_runner.parsing():
try:
if not execution_context.graphql_document:
execution_context.graphql_document = parse_document(query)
except GraphQLError as error:
execution_context.errors = [error]
return ExecutionResult(
data=None,
errors=[error],
extensions=await extensions_runner.get_extensions_results(),
)

except Exception as error: # pragma: no cover
error = GraphQLError(str(error), original_error=error)

execution_context.errors = [error]
return ExecutionResult(
data=None,
errors=[error],
extensions=await extensions_runner.get_extensions_results(),
)
except GraphQLError as error:
execution_context.errors = [error]
return ExecutionResult(
data=None,
errors=[error],
extensions=await extensions_runner.get_extensions_results(),
)

except Exception as error: # pragma: no cover
error = GraphQLError(str(error), original_error=error)

execution_context.errors = [error]
return ExecutionResult(
data=None,
errors=[error],
extensions=await extensions_runner.get_extensions_results(),
)

async with extensions_runner.validation():
_run_validation(execution_context)
Expand Down Expand Up @@ -137,27 +137,27 @@ def execute_sync(
# Note: In graphql-core the schema would be validated here but in
# Strawberry we are validating it at initialisation time instead

try:
with extensions_runner.parsing():
with extensions_runner.parsing():
try:
if not execution_context.graphql_document:
execution_context.graphql_document = parse_document(query)
except GraphQLError as error:
execution_context.errors = [error]
return ExecutionResult(
data=None,
errors=[error],
extensions=extensions_runner.get_extensions_results_sync(),
)

except Exception as error: # pragma: no cover
error = GraphQLError(str(error), original_error=error)

execution_context.errors = [error]
return ExecutionResult(
data=None,
errors=[error],
extensions=extensions_runner.get_extensions_results_sync(),
)
except GraphQLError as error:
execution_context.errors = [error]
return ExecutionResult(
data=None,
errors=[error],
extensions=extensions_runner.get_extensions_results_sync(),
)

except Exception as error: # pragma: no cover
error = GraphQLError(str(error), original_error=error)

execution_context.errors = [error]
return ExecutionResult(
data=None,
errors=[error],
extensions=extensions_runner.get_extensions_results_sync(),
)

with extensions_runner.validation():
_run_validation(execution_context)
Expand Down
46 changes: 46 additions & 0 deletions tests/schema/extensions/test_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,3 +292,49 @@ def string(self) -> str:
schema.execute_sync(query)
msg = "Cannot use async extension hook during sync execution"
assert str(exc_info.value) == msg


@pytest.mark.asyncio
async def test_dont_swallow_errors_in_parsing_hooks():
class MyExtension(Extension):
def on_parsing_start(self):
raise Exception("This shouldn't be swallowed")

@strawberry.type
class Query:
@strawberry.field
def ping(self) -> str:
return "pong"

schema = strawberry.Schema(query=Query, extensions=[MyExtension])
query = "query { string }"

with pytest.raises(Exception, match="This shouldn't be swallowed"):
schema.execute_sync(query)

with pytest.raises(Exception, match="This shouldn't be swallowed"):
await schema.execute(query)


def test_on_parsing_end_called_when_errors():
execution_errors = False

class MyExtension(Extension):
def on_parsing_end(self):
nonlocal execution_errors
execution_context = self.execution_context
execution_errors = execution_context.errors

@strawberry.type
class Query:
@strawberry.field
def ping(self) -> str:
return "pong"

schema = strawberry.Schema(query=Query, extensions=[MyExtension])
query = "query { string" # Invalid query

result = schema.execute_sync(query)
assert result.errors

assert result.errors == execution_errors

0 comments on commit d79aa61

Please sign in to comment.