一.全局异常处理
def dispatch(self, request, *args, **kwargs):
try:
self.initial(request, *args, **kwargs)
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
response = handler(request, *args, **kwargs)
except Exception as exc:
response = self.handle_exception(exc)
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
-主动抛的非drf异常
-程序出错了
都不会被处理
我们的目标,无论主动抛还是程序运行出错,都同意返回规定格式--》能记录日志
公司里一般返回 {code:999,'msg':'系统错误,请联系系统管理员'}
'第一步:首先在drf的配置文件中有一个配置信息如下(这个后面再配置,先挑出来讲而已)'
'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
'这个配置就是处理drf内部异常的配置文件,如果我们想要进行自定义,就需要在dango的配置文件中自行注册进行替换'
'第二步:我们查看dispatch中的异常捕获,发现handle_exception处理了这些异常捕获的信息,而他的参数就是错误信息'
response = self.handle_exception(exc)
'第三步:我们进入他的源码发现他返回的信息是response,并且这个response是由exception_handler方法获得的'
def handle_exception(self, exc):
if isinstance(exc, (exceptions.NotAuthenticated,
exceptions.AuthenticationFailed)):
auth_header = self.get_authenticate_header(self.request)
if auth_header:
exc.auth_header = auth_header
else:
exc.status_code = status.HTTP_403_FORBIDDEN
exception_handler = self.get_exception_handler()
context = self.get_exception_handler_context()
response = exception_handler(exc, context)
if response is None:
self.raise_uncaught_exception(exc)
response.exception = True
return response
'第四步:我们可以看到他则是来自上面的一行代码'
exception_handler = self.get_exception_handler()
'第五步:进入这个get_exception_handler方法的源码,我们可以发现他就是拿了配置文件中的配置返回出去'
def get_exception_handler(self):
return self.settings.EXCEPTION_HANDLER
'而配置信息中对应的是一个函数,因此exception_handler的值就相当于是获取这个函数的结果'
def exception_handler(exc, context):
if isinstance(exc, Http404):
exc = exceptions.NotFound()
elif isinstance(exc, PermissionDenied):
exc = exceptions.PermissionDenied()
if isinstance(exc, exceptions.APIException):
headers = {}
if getattr(exc, 'auth_header', None):
headers['WWW-Authenticate'] = exc.auth_header
if getattr(exc, 'wait', None):
headers['Retry-After'] = '%d' % exc.wait
if isinstance(exc.detail, (list, dict)):
data = exc.detail
else:
data = {'detail': exc.detail}
set_rollback()
return Response(data, status=exc.status_code, headers=headers)
return None
'研究了源码之后我们就开始自己编写,因为原本的异常处理函数有两个参数,因此我们也需要上两个参数,而它的源码太多了,我们可以跟面向对象的派生方法一样,在我们自行定义的函数内调用原本的函数,在此基础上进行自定义'
def common_exception_handler(exc, context):
print('时间,登录用户id,用户ip,请求方式,请求地址,执行的视图类,错误原因')
res = exception_handler(exc, context)
if res:
res = Response(data={'code': 888, 'msg': res.data.get('detail', '请联系系统管理员')})
else:
res = Response(data={'code': 999, 'msg': '系统错误,请联系系统管理员'})
return res
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'app01.exceptions.common_exception_handler',
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?