重写异常模块目的是记录异常信息(项目上线)python
一、在settings的drf配置中配置EXCEPTION_HANDLER,指向自定义的exception_handler函数django
二、异常模块:django项目的全部异常都会被处理,drf能处理的会本身处理(4xx),不能处理的交给django处理(5xx)改写exception_handler,在全局配置api
二、drf出现异常了,都会回调exception_handler函数,携带 异常对象和异常相关信息内容,在exception_handler函数完成异常信息的返回以及异常信息的logging日志服务器
核心:异常信息都须要被logging记录,因此须要自定义;drf只处理客户端异常,服务器异常须要手动处理,统一处理结果函数
REST_FRAMEWORK = { # 异常 # 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',#系统异常 'EXCEPTION_HANDLER': 'api.utils.exception_handler',#重写异常 }
#测试 from rest_framework.response import Response def exception_handler(exc, condent): print(exc)#错误信息 print(condent)#错误来源 return Response({ 'msg':"异常" })
from rest_framework.response import Response def exception_handler(exc, context): # 开发阶段必定要记录日志 # logging.error(exc) return Response('%s - %s' % (context['view'].__class__.__name__, exc))
from rest_framework.response import Response from rest_framework.views import exception_handler as drf_exception_handler def exception_handler(exc, context): response = drf_exception_handler(exc, context) if response is None: # drf没有处理的异常 response = Response({'detail': '%s' % exc}) # 项目阶段,要记录到日志文件 return response
""" 返回数据类型 response = { 'status': 7, 'exc': '异常信息' } """ from rest_framework.response import Response from rest_framework.views import exception_handler as drf_exception_handler from rest_framework import status def exception_handler(exc, context): response = drf_exception_handler(exc, context) if response is None: # drf没有处理的异常(服务器异常) return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR, data={ 'status': 7, 'exc': '%s' % exc }) #设置状态码 # 项目阶段,要记录到日志文件 return Response(status=response.status_code, data={ 'status': 7, # drf处理的客户端异常,原始处理方式是将异常信息放在response对象的data中,data的格式是{'datail': '具体的异常信息'} 'exc': '%s' % response.data.get('detail') })
from rest_framework.views import exception_handler as drf_exception_handler from rest_framework.response import Response def exception_handler(exc, context): # drf_exception_handler的执行结果就是异常信息的Response对象或None # 是Response对象能够直接返回 # 是None能够从exc中拿到异常信息,从context拿到是谁出现的异常,本身格式化成Response对象返回 # 重点:自定义异常模块目的是记录异常信息到日志文件 - 产品阶段 response = drf_exception_handler(exc, context) if response is None: response = Response({'detail': '%s' % exc}, status=500, exception=True) # logging.error(response.data) return response
一、在APIView的dispatch方法中,有一个超大的try...except...,将代码运行异常都交给异常处理模块处理self.handle_exception(exc)
二、从配置中映射出配置处理异常的函数(自定义异常模块就是自定义配置指向本身的函数):self.get_exception_handler()
三、异常函数exception_handler(exc, context)处理异常,就会走本身的:
先交给系统处理(客户端的异常),系统没处理(服务器异常),再本身处理源码分析