graphql-python / graphql-python/graphql-core-legacy
AsyncioExecutor produces hard to debug errors
- Dominant language
- Python
- Stars
- 372
- Forks
- 175
- PR merge metrics
- No merged PRs in 30d
Description
When an `async` resolver is raising an exception, this exception is not logged and its stack in lost and never printed. The only "report" is the error carried by the `ExecutionResult` but we can only access its type and message, not the actual stack trace.
This is different for sync resolvers (even when using the `AsyncioExecutor`): the exception is printed by `graphql.execution.executor resolve_or_error`.
Below is an example to illustrate the issue:
```python
from graphql.execution.executors.asyncio import AsyncioExecutor
from graphql import GraphQLObjectType, GraphQLField, GraphQLString, GraphQLSchema, graphql
def resolve_hello(root, args, context, info):
raise Exception("wololo")
async def resolve_hello_async(root, args, context, info):
raise Exception("wololo")
QueryType = GraphQLObjectType("Query", fields={
"hello": GraphQLField(GraphQLString, resolver=resolve_hello),
"helloAsync": GraphQLField(GraphQLString, resolver=resolve_hello_async),
})
schema = GraphQLSchema(query=QueryType)
print("Sync execution")
result = graphql(schema, '{ hello }', executor=AsyncioExecutor())
# This will log something like:
#
# An error occurred while resolving field Query.hello
# Traceback (most recent call last):
# File ".../site-packages/graphql/execution/executor.py", line 200, in resolve_or_error
# return executor.execute(resolve_fn, source, args, context, info)
# File ".../site-packages/graphql/execution/executors/asyncio.py", line 50, in execute
# result = fn(*args, **kwargs)
# File "test.py", line 11, in resolve_hello
# raise Exception("wololo")
# Exception: wololo
# As a side note, the produced error have a correct stack trace:
print(result.errors[0].stack) #
print("=" * 10)
print("Async execution")
async_result = graphql(schema, '{ helloAsync }', executor=AsyncioExecutor())
# While producing the same result, it won't log anything, and good luck to know where
# the error comes from.
# This error has None as a stack trace:
print(async_result.errors[0].stack) # None
```
I am a beginner with python async stuff so I won't send a PR, but as a temporary solution I am replacing the `AsyncioExecutor execute` method with something like that:
```python
def execute(self, fn, *args, **kwargs):
result = fn(*args, **kwargs)
if isinstance(result, Future) or iscoroutine(result):
async def hop():
try:
awaited_result = await result
except Exception as e:
logger.exception("Exception in %s", fn)
raise
return awaited_result
future = ensure_future(hop(), loop=self.loop)
# future = ensure_future(result, loop=self.loop)
self.futures.append(future)
return Promise.resolve(future)
return result
```
EDIT: I am using graphene 1.4 and graphql 1.1
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.