graphql-python / graphene

GraphQL framework for Python
http://graphene-python.org/
MIT License
8.07k stars 822 forks source link

intelligible errors on schema creation. #1315

Open blueforesticarus opened 3 years ago

blueforesticarus commented 3 years ago

When creating a schema, if there is a problem with one of your QueryObjects, the resulting error message and traceback does not give any indication as to which ObjectType class is broken.

ex)

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/user/sonicsd/src/api/graphql.py", line 30, in schema
  File "/usr/local/lib/python3.7/dist-packages/graphene/types/schema.py", line 78, in __init__
    self.build_typemap()
  File "/usr/local/lib/python3.7/dist-packages/graphene/types/schema.py", line 168, in build_typemap
    initial_types, auto_camelcase=self.auto_camelcase, schema=self
  File "/usr/local/lib/python3.7/dist-packages/graphene/types/typemap.py", line 80, in __init__
    super(TypeMap, self).__init__(types)
  File "/usr/local/lib/python3.7/dist-packages/graphql/type/typemap.py", line 31, in __init__
    self.update(reduce(self.reducer, types, OrderedDict()))  # type: ignore
  File "/usr/local/lib/python3.7/dist-packages/graphene/types/typemap.py", line 88, in reducer
    return self.graphene_reducer(map, type)
  File "/usr/local/lib/python3.7/dist-packages/graphene/types/typemap.py", line 117, in graphene_reducer
    return GraphQLTypeMap.reducer(map, internal_type)
  File "/usr/local/lib/python3.7/dist-packages/graphql/type/typemap.py", line 109, in reducer
    field_map = type_.fields
  File "/usr/local/lib/python3.7/dist-packages/graphql/pyutils/cached_property.py", line 22, in __get__
    value = obj.__dict__[self.func.__name__] = self.func(obj)
  File "/usr/local/lib/python3.7/dist-packages/graphql/type/definition.py", line 198, in fields
    return define_field_map(self, self._fields)
  File "/usr/local/lib/python3.7/dist-packages/graphql/type/definition.py", line 217, in define_field_map
    ).format(type_)
AssertionError: Query fields must be a mapping (dict / OrderedDict) with field names as keys or a function which returns such a mapping.

In the error there should at least be the name of the Query class whose fields are invalid. In this case I believe the error turned out to be that the root Query had no fields because I was improperly dynamically generating them.

blueforesticarus commented 3 years ago

Okay, I completely missed that "Query" was the class name.

Either way I think this error message is pretty unhelpful. For example, I get the exact same thing with:

class GQL_Free(graphene.Mutation):
    class Arguments:
        id = graphene.ID()

    histo = GQL_Histo()
    def mutate(id):
        h = histograms[id]
        h.free()
        return GQL_Free(histo=h)
AssertionError: GQL_Free fields must be a mapping (dict / OrderedDict) with field names as keys or a function which returns such a mapping.