Closed
@magicmark

Description

Repro

import asyncio
from graphql import (
    graphql,
    GraphQLSchema,
    GraphQLObjectType,
    GraphQLField,
    GraphQLNonNull,
    GraphQLString,
)


async def resolve_foo(obj, info):
    return "foo!"


def resolve_bar(obj, info):
    raise Exception('yikes')


schema = GraphQLSchema(
    query=GraphQLObjectType(
        name="RootQueryType",
        fields={
            "foo": GraphQLField(GraphQLNonNull(GraphQLString), resolve=resolve_foo),
            "bar": GraphQLField(GraphQLNonNull(GraphQLString), resolve=resolve_bar),
        },
    )
)

result = asyncio.run(graphql(schema, "{ foo bar }"))
print(result)

Prints

$ python3 test2.py
ExecutionResult(data=None, errors=[GraphQLError('yikes', locations=[SourceLocation(line=1, column=7)], path=['bar'])])
sys:1: RuntimeWarning: coroutine 'ExecutionContext.execute_field.<locals>.await_result' was never awaited
sys:1: RuntimeWarning: coroutine 'resolve_foo' was never awaited

Version info

$ pip freeze | grep graphql-core
graphql-core==3.2.6

I'm guessing what could be happening here is that:

  • non-nullable field error (bar) bubbles up and cancels execution for the rest of the type's fields
  • ...but we already kicked off the foo async resolver function
  • ...but by aborting, we don't ever unwrap the future / await the result for, hence the warning.

Which makes total sense -- and indeed if we do schema.execute("{ bar foo }") we don't see the warning printed -- because the async function never even gets kicked off.

I think maybe we need to be calling task.cancel() or .close() somewhere?

(originally misatttributed to strawberry strawberry-graphql/strawberry#3820)

Thanks!