【发布时间】:2020-01-29 14:31:14
【问题描述】:
每当引发异常时,它们都会记录在控制台中(如果使用了 Sentry,也会记录在其中)。
其中许多例外只是为了向用户显示。例如,django-graphql-jwt raises the PermissionDenied exception 代表 login_required decorator。
问题是这会在测试/开发期间污染控制台输出,并在生产期间将有效错误记录到 Sentry。对于上述示例等例外情况,仅用于向用户显示,没有记录。
作为一种解决方法,我尝试编写中间件来捕获任何抛出的异常:
class ExceptionFilterMiddleware:
IGNORED_EXCEPTIONS = (
# Local exceptions
ValidationException,
# Third-party exceptions
JSONWebTokenExpired,
PermissionDenied,
)
def on_error(self, error):
if not isinstance(error, self.IGNORED_EXCEPTIONS):
return error
def resolve(self, next, *args, **kwargs):
return next(*args, **kwargs).catch(self.on_error)
但如果异常被捕获或未返回,则它不再填充查询/变异输出中的errors 字段。因此,所有错误都会被记录,无法有条件地记录异常。
这意味着唯一的解决方案是创建一个日志过滤器,如下所示:
def skip_valid_exceptions(record):
"""
Skip exceptions for errors only intended to be displayed to the API user.
"""
skip: bool = False
if record.exc_info:
exc_type, exc_value = record.exc_info[:2]
skip = isinstance(exc_value, valid_exceptions)
return not skip
但这也不起作用,因为每当 Graphene 抛出错误时,record.exc_info 就是 None,因此无法根据异常类型有条件地过滤掉异常。
有解决办法吗?这似乎是一个常见问题,但我找不到任何解决方案。
或者,我不能使用异常向 API 用户显示错误,但这意味着将错误放入查询结果的 data.errors 字段而不是 errors。这是一个标准,需要适配前端逻辑(比如 Apollo 的错误处理),并不理想。这也意味着不能使用第三方库(如 django-graphql-jwt)中抛出异常的任何功能。
【问题讨论】:
-
您找到解决方案了吗?我现在自己处理这个问题
-
@JensAstrup 这是很久以前的事了,但是 IIRC 我认为我没有找到任何解决方案。 graphene-django 对此的处理相当差。我在 GitHub 上打开了一个问题,但什么也没发生:github.com/graphql-python/graphene-django/issues/780
标签: django graphene-python graphene-django