異常模塊

異常模塊(重點)

重寫異常模塊目的是記錄異常信息(項目上線)python

一、在settings的drf配置中配置EXCEPTION_HANDLER,指向自定義的exception_handler函數django

二、異常模塊:django項目的全部異常都會被處理,drf能處理的會本身處理(4xx),不能處理的交給django處理(5xx)改寫exception_handler,在全局配置api

二、drf出現異常了,都會回調exception_handler函數,攜帶 異常對象和異常相關信息內容,在exception_handler函數完成異常信息的返回以及異常信息的logging日誌服務器

核心:異常信息都須要被logging記錄,因此須要自定義;drf只處理客戶端異常,服務器異常須要手動處理,統一處理結果函數

用法

  1. 主要是用來記錄系統的錯誤,方便進行修改,特別重要,出現異常就要進行記錄。
  2. 重寫異常

配置settings.py

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')
    })

在使用drf的時候,驗證與is_valid(raise_exception=True)衝突,所以使用

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)處理異常,就會走本身的:
先交給系統處理(客戶端的異常),系統沒處理(服務器異常),再本身處理源碼分析

相關文章
相關標籤/搜索