无论何时引发异常,它们都会记录在控制台中(如果使用了Sentry,还会记录在Sentry中)。
这些异常中的许多只打算显示给用户。例如django-graphql-jwt引发PermissionDenied异常对于login_required装饰者。
问题是,这会在测试/开发期间污染控制台输出,并在生产期间将有效错误记录到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但这也行不通,因为record.exc_info是None因此,每当使用Graphene抛出错误时,都不可能根据其类型有条件地过滤掉异常。
有解决方案吗?这似乎是一个常见的问题,但我很难找到任何解决方案。
或者,我可以不使用异常向API用户显示错误,但这意味着将错误放入查询结果的data.errors字段,而不是errors。这是一个标准,需要调整前端逻辑(例如Apollo的错误处理),这并不理想。这也意味着不能从抛出异常的第三方库(如django-graphql-jwt)中使用任何功能。
发布于 2020-11-17 02:49:11
试试这个。首先,确保预期的异常是GraphQLError或者它的后代。
然后创建一个日志过滤器,如下所示:
import logging
from graphql import GraphQLError
class GraphQLLogFilter(logging.Filter):
"""
Filter GraphQL errors that are intentional.
Any exceptions of type GraphQLError that are raised on purpose
to generate errors for GraphQL responses will be silenced from logs.
Other exceptions will be displayed so they can be tracked down.
"""
def filter(self, record):
if record.exc_info:
etype, _, _ = record.exc_info
if etype == GraphQLError:
return None
if record.stack_info and 'GraphQLError' in record.stack_info:
return None
if record.msg and 'GraphQLError' in record.msg:
return None
return True在您的设置中使用:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
},
# Prevent graphql exception from displaying in console
'filters': {
'graphql_log_filter': {
'()': GraphQLLogFilter,
}
},
'loggers': {
'graphql.execution.utils': {
'level': 'WARNING',
'handlers': ['console'],
'filters': ['graphql_log_filter'],
},
},
}相关资源:
https://stackoverflow.com/questions/58165464
复制相似问题