如何为石墨烯/ django-graphene中的错误返回自定义JSON响应?

时间:2018-03-18 15:31:41

标签: graphene-python

我想将状态字段添加到错误响应中,而不是这样:

{
  "errors": [
    {
      "message": "Authentication credentials were not provided",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ]
    }
  ],
  "data": {
    "viewer": null
  }
}

应该是这样的:

{
  "errors": [
    {
      "status": 401,  # or 400 or 403 or whatever error status suits
      "message": "Authentication credentials were not provided",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ]
    }
  ],
  "data": {
    "viewer": null
  }
}

我发现我只能通过在解析器中添加Exception来更改消息:raise Error('custom error message'),但是如何添加字段?

代码示例:

class Query(UsersQuery, graphene.ObjectType):
    me = graphene.Field(SelfUserNode)

    def resolve_me(self, info: ResolveInfo):
        user = info.context.user
        if not user.is_authenticated:
            # but status attr doesn't exist...
            raise GraphQLError('Authentication credentials were not provided', status=401)  
        return user

2 个答案:

答案 0 :(得分:1)

我没有找到一种方法以你提出的方式解决你的问题,否则我会像这样扩展slice()类:

LoginRequiredMixin

并在您的网址中:

class LoginRequiredMixin:
    def dispatch(self, info, *args, **kwargs):
        if not info.user.is_authenticated:
            e =  HttpError(HttpResponse(status=401, content_type='application/json'), 'Please log in first')
            response = e.response
            response.content = self.json_encode(info, [{'errors': [self.format_error(e)]}])
            return response

            return super().dispatch(info, *args, **kwargs)

class PrivateGraphQLView(LoginRequiredMixin, GraphQLView):
    schema=schema

您无法通过graphiql查看状态,但在您的客户端中,您可以在标题中获取该状态,或者您可以修改此行以添加回复from django.views.decorators.csrf import csrf_exempt from educor.schema import PrivateGraphQLView url(r'^graphql', csrf_exempt(PrivateGraphQLView.as_view(batch=True))) 。希望它无论如何我都会给你留下另一个可能的解决方案https://github.com/graphql-python/graphene-django/issues/252

答案 1 :(得分:1)

使用以下命令更新默认的GraphQLView

from graphene_django.views import GraphQLView as BaseGraphQLView


class GraphQLView(BaseGraphQLView):

    @staticmethod
    def format_error(error):
        formatted_error = super(GraphQLView, GraphQLView).format_error(error)

        try:
            formatted_error['context'] = error.original_error.context
        except AttributeError:
            pass

        return formatted_error


urlpatterns = [
    path('api', GraphQLView.as_view()),
]

这将在引发的任何异常中寻找context属性。如果存在,它将使用此数据填充错误。

现在,您可以为填充context属性的不同用例创建例外。在这种情况下,您想将状态代码添加到错误中,下面是一个示例示例:

class APIException(Exception):

    def __init__(self, message, status=None):
        self.context = {}
        if status:
            self.context['status'] = status
        super().__init__(message)

您将像这样使用它:

raise APIException('Something went wrong', status=400)