我有一个与 Django 应用程序关联的 GraphQL 系统,该系统似乎工作正常,只是它完全忽略了突变中的错误。也就是说,如果突变执行时没有错误,则一切都会按预期运行。但是,如果我在突变的第一行引发异常,我不会收到任何错误指示——应用程序日志中没有任何内容,并且 graphQL 响应只是一个 json 将为空内容,例如:
{
"data": {
"exampleMutation": {
"mutationResponseSchema": null
}
}
}
即使我将 django 片段(例如尝试获取过滤器集)包装在 try: except: 中,其行为也与引发异常相同。 IOW,抛出异常(即使已处理)似乎会触发发送空响应。
我完全不知道这些异常的去向——似乎遇到异常时的行为是忽略它并只返回一个 null JSON。
此外,我有一个具有相同基本布局的应用程序,但基于较旧的 Python 映像构建(3.8 与 3.11 的这个版本相比,因此 django/graphene 版本和相关依赖项较新)。旧应用程序像往常一样处理异常,并且当使用与我遇到问题的结构相同的 Django/Graphene 类引发时,会通过端点返回消息。
我不知道石墨烯的错误处理是否发生了变化,但我似乎找不到明确的答案。
例如,如果我写以下突变:
class ExampleMutation(graphene.Mutation):
class Arguments:
fail_here = graphene.String()
some_schema = graphene.Field(SomeSchema)
@authorized
def mutate(root, info, user, **kwargs):
# could also just raise Exception('automatic exception') here and get same behavior.
if kwargs.get('fail_here') == 'yes':
raise Exception('text') # Doesn't seem to matter what exception is raised
else:
django_model = SomeSchemaModel.objects.first()
return ExampleMutation(some_schema=django_model)
对例如的回应
mutation exampleMutation($failHere: String){
exampleMutation(
failHere: $failHere,
) {
someSchema
{
field1
field2
}
}
}
如果使用例如调用突变,则是有效的并且行为符合预期{“失败这里”:“否”}。因此,graphQL/Django 的结构不是问题。
问题是,当使用 {"failHere": "yes"} 调用端点时(或者如果我只是在突变的第一行引发错误),响应是:
{
"data": {
"exampleMutation": {
"someSchema": null
}
}
}
以上可能是一个bug,我发布到github上。但如果其他人也遇到这种情况,这是让事情正常运转的解决方法:
在 django 的设置中(使用适合您的应用程序的架构):
GRAPHENE = {
'SCHEMA': 'core.graphql.index.schema',
'MIDDLEWARE': ['graphene_django.debug.middleware.DjangoDebugMiddleware'],
}
我不确定这一点,但我从一些搜索中发现,也许使用较新版本的 graphene-django,DjangoDebugMiddleware 中间件需要在 JSON 响应中发送这些异常。
无论如何,真正的问题是 GraphQLView 处理程序似乎需要的中间件不是作为列表发送(如上面所示的设置所要求的),而是作为 double 列表发送,这可以通过重写这样的实例化来实现:
from graphene_django.views import GraphQLView, graphene_settings
class GQLView(GraphQLView):
def __init__(self, *args, **kwargs):
kwargs.update({'middleware':[graphene_settings.MIDDLEWARE]}) #note the extra list level
super().__init__(*args, **kwargs)
然后在 urls.py 中你会得到类似的内容:
urlpatterns = [
# Graphql
(r'graphql', GQLView.as_view())
]