Django Graphene 不处理错误

问题描述 投票:0回答:1

我有一个与 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
        }
    }
}
python graphql graphene-python graphene-django
1个回答
1
投票

以上可能是一个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())
]
© www.soinside.com 2019 - 2024. All rights reserved.