重寫異常模塊目的是記錄異常信息(項目上線)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)處理異常,就會走本身的:
先交給系統處理(客戶端的異常),系統沒處理(服務器異常),再本身處理源碼分析