1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
from dataclasses import dataclass
from logging import getLogger
from typing import Any
import graphql
from graphql.utilities import print_schema
from apischema.graphql import graphql_schema, resolver
logger = getLogger(__name__)
def log_error(
error: Exception, obj: Any, info: graphql.GraphQLResolveInfo, **kwargs
) -> None:
logger.error(
"Resolve error in %s", ".".join(map(str, info.path.as_list())), exc_info=error
)
return None
@dataclass
class Foo:
@resolver(error_handler=log_error)
def bar(self) -> int:
raise RuntimeError("Bar error")
@resolver
def baz(self) -> int:
raise RuntimeError("Baz error")
def foo(info: graphql.GraphQLResolveInfo) -> Foo:
return Foo()
schema = graphql_schema(query=[foo])
# Notice that bar is Int while baz is Int!
schema_str = """\
type Query {
foo: Foo!
}
type Foo {
bar: Int
baz: Int!
}"""
assert print_schema(schema) == schema_str
# Logs "Resolve error in foo.bar", no error raised
assert graphql.graphql_sync(schema, "{foo{bar}}").data == {"foo": {"bar": None}}
# Error is raised
assert graphql.graphql_sync(schema, "{foo{baz}}").errors[0].message == "Baz error"
|