Django筆記三十一之全域性異常處理

XHunter發表於2023-04-26

本文首發於公眾號:Hunter後端

原文連結:Django筆記三十一之全域性異常處理

這一篇筆記介紹 Django 的全域性異常處理。

當我們在處理一個 request 請求時,會盡可能的對介面資料的格式,內部呼叫的函式做一些異常處理,但可能還是會有一些意想不到的漏網之魚,造成程式的異常導致不能正常執行,甚至會直接報給前端一個錯誤。

為了避免這種情況的發生,令我們的後端服務看起來是正常的,就算有報錯也可以很體面的給前端一個提示,以及後端做一些錯誤日誌的記錄,這裡我們引入全域性異常的處理。

這裡我們會用 Django 的中介軟體和日誌的處理來實現,在本系列文章的第二十九篇和第三十篇,可以先熟悉下這兩部分功能的使用。

在介紹中介軟體的章節,我們介紹了 __call__() 和 process_view() 函式,其實還有一個 process_exception() 函式,這個函式就是當我們的請求在發生不可預知的報錯的情況下,會自動呼叫的函式。

我們來看這樣一個處理的示例:

# hunter/middlewares/exception_middleware.py

import traceback
from django.http import JsonResponse
import logging

logger = logging.getLogger(__name__)


class ExceptionMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_exception(self, request, exception):

        traceback_info = traceback.format_exc()
        logger.info(f"request_path: {request.path}, traceback_info: {traceback_info}")
        return JsonResponse({"code": -1, "msg": "error"}, status=500)

在這裡,我們使用 traceback.format_exc() 函式獲取到 exception 的報錯資訊,然後透過 logger 日誌列印輸出。

日誌資訊

這裡我們主要輸出兩個資訊,一個是介面請求的路徑,request.path,一個是報錯資訊 traceback_info,當然,這裡我們還可以記錄更多的資訊,比如請求的使用者資訊,請求的引數等。

記錄之後,後端就可以透過日誌的具體資訊去檢視到底是哪裡出了問題。

返回報錯

在這裡,呼叫 process_exception() 函式之後,我們這裡直接 return 了 response,還有一個 http 的狀態碼 status=500,這些資訊都是可以自己擬定的,到時候和前端約定好,檢測返回了某個狀態碼比如 500,然後就友好的顯示某個報錯彈窗資訊,比如後臺正在處理報錯等。

呼叫中介軟體

定義好這個中介軟體之後,我們就需要在 settings.py 裡去引用這個中介軟體,比如這個中介軟體我們放置的目錄是 hunter/middlewares/exception_middleware.py,就需要在 hunter/settings.py 的 MIDDLEWARE 末尾加上 'hunter.middlewares.exception_middleware.ExceptionMiddleware', 這一條。

# hunter/settings.py

MIDDLEWARE = [
    ...
    'hunter.middlewares.exception_middleware.ExceptionMiddleware',
]

測試報錯

我們去嘗試觸發報錯資訊,比如之前在 第二十九篇筆記中寫的一個介面,這裡我們修改一下,直接報錯:

# blog/views.py

from django.http import HttpResponse, JsonResponse

def time_view(request):
    html = "<h1>abc</h1>"
    1 / 0
    return HttpResponse(html)

然後在頁面或者 postman 裡呼叫該介面,就可以在 logger 指定的日誌檔案裡看到關於這一行的具體報錯資訊啦。

以上就是本篇筆記的全部內容,接下來我會接著介紹一下 Django 裡 session 的一個簡單應用,也就是說如何判斷使用者是否登入的一個示例。

如果想獲取更多後端相關文章,可掃碼關注閱讀:

image

相關文章