graphql-python / graphql-core-legacy

GraphQL base implementation for Python (legacy version – see graphql-core for the current one)
MIT License
374 stars 183 forks source link

Query execution hangs forever when BaseException is thrown #225

Open Alexander3 opened 5 years ago

Alexander3 commented 5 years ago

If BaseExcetion will occur during query execution everything hangs. I've tried different executors, but this doesn't help. I used SystemExit in example for brevity. My real situation was pytest-django throwing exception when you try to access database.

Example code

import graphene
from graphene.test import Client

class CreatePerson(graphene.Mutation):
    ok = graphene.Boolean()

    def mutate(self, info):
        # Throwing sth that derives from BaseExcetion instead of Exception here causes freeze
        raise SystemExit

class Mutation(graphene.ObjectType):
    create_person = CreatePerson.Field()

schema = graphene.Schema(mutation=Mutation)
Client(schema).execute('''
    mutation{
        createPerson{
            ok
        }
    }
    ''')

My debugger shows that it's freezed on this line. Inside get promise calls wait() and waits forever. https://github.com/graphql-python/graphql-core/blob/master/graphql/execution/executor.py#L147

Full traceback ``` File "/home/bond/.PyCharm2018.3/config/scratches/scratch_4.py", line 26, in ''') File "python3.7/site-packages/graphene/test/__init__.py", line 40, in execute executed = self.schema.execute(*args, **dict(self.execute_options, **kwargs)) File "python3.7/site-packages/graphene/types/schema.py", line 102, in execute return graphql(self, *args, **kwargs) File "python3.7/site-packages/graphql/graphql.py", line 44, in graphql return execute_graphql(*args, **kwargs) File "python3.7/site-packages/graphql/graphql.py", line 70, in execute_graphql **execute_options File "python3.7/site-packages/graphql/backend/core.py", line 34, in execute_and_validate return execute(schema, document_ast, *args, **kwargs) File "python3.7/site-packages/graphql/execution/executor.py", line 147, in execute return promise.get() File "python3.7/site-packages/promise/promise.py", line 509, in get self._wait(timeout or DEFAULT_TIMEOUT) File "python3.7/site-packages/promise/promise.py", line 504, in _wait self.wait(self, timeout) ```

Solution

Looks like it should be caught here: https://github.com/graphql-python/graphql-core/blob/master/graphql/execution/executors/utils.py#L20 https://github.com/graphql-python/graphql-core/blob/master/graphql/execution/executor.py#L448 Am I right?

rcjsuen commented 5 years ago

I also have this problem. I'm trying to write a test and it seems to hang forever with a (seemingly) harmless GraphQL query.

{
  emailLists {
    name
  }
}

https://github.com/graphql-python/graphql-core/blob/9202021fc87db9c175e115016cd53e5d9d085ac6/graphql/execution/executor.py#L142

If I skip the None bit here and change the code instead, the test will complete but it is not quite right (unsurprisingly).

Promise.resolve(promise_executor).catch(on_rejected).then(on_resolve)
E       AssertionError: assert {'data': <fun...7f6fc0253488>} == {'data': {'hey': 'hello!'}}
E         Differing items:
E         {'data': <function execute.<locals>.promise_executor at 0x7f6fc0253488>} != {'data': {'hey': 'hello!'}}
E         Use -v to get the full diff

Naturally, ignore the 'hey': 'hello!' bit as I'm just copy/pasting from the example directly right now.

PascalSun commented 5 years ago

I have the same issue, the execution just hang in the promise.get() line, I have tried to fork and debug the issue, and found in fact, we can set the timeout for promise.get(timeout=5) , so the execution will not hang there.