DRF之異常捕獲原始碼分析
【一】異常捕獲介紹
- Django Rest Framework(DRF)是一個用於構建Web API的強大框架,它提供了一種處理異常的機制,使開發人員能夠捕獲和處理各種異常情況。
- DRF中的異常捕獲類是用於捕獲和處理這些異常的關鍵元件之一。
【二】異常捕獲流程分析
# 全域性異常處理
# 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
- 透過上述配置
- 在該函式中,可以執行一些自定義的操作來處理異常
【三】exception_handler原始碼分析
# exc: 這是引發的異常物件,它是一個Python異常類的例項。
# context: 這是一個字典,包含了有關異常上下文的資訊,通常包括請求物件和檢視物件等。
def exception_handler(exc, context):
"""
Returns the response that should be used for any given exception.
By default we handle the REST framework `APIException`, and also
Django's built-in `Http404` and `PermissionDenied` exceptions.
Any unhandled exceptions may return `None`, which will cause a 500 error
to be raised.
"""
# exception_handler 函式首先檢查異常物件 exc 的型別,然後根據異常型別返回適當的HTTP響應
if isinstance(exc, Http404):
# 如果異常是 Http404 型別(即頁面不存在),則將其替換為 DRF 中的 NotFound 異常。
exc = exceptions.NotFound()
elif isinstance(exc, PermissionDenied):
# 如果異常是 PermissionDenied 型別(即許可權被拒絕),則將其替換為 DRF 中的 PermissionDenied 異常。
exc = exceptions.PermissionDenied()
# 檢查異常是否屬於 APIException 型別,這是DRF中異常的基類
# 如果是 APIException 型別
if isinstance(exc, exceptions.APIException):
# 它將為異常設定HTTP響應的頭資訊(如認證頭和重試頭)
headers = {}
# 如果異常具有 auth_header 屬性,將該屬性的值新增到響應的 WWW-Authenticate 頭資訊中。
# 這通常用於處理身份驗證相關的異常。
if getattr(exc, 'auth_header', None):
# 並將異常的詳細資訊包裝在響應資料中
headers['WWW-Authenticate'] = exc.auth_header
# 如果異常具有 wait 屬性,將該屬性的值新增到響應的 Retry-After 頭資訊中。
# 這通常用於指示客戶端應該等待多長時間後再次嘗試請求。
if getattr(exc, 'wait', None):
# 並將異常的詳細資訊包裝在響應資料中
headers['Retry-After'] = '%d' % exc.wait
# 根據異常的 detail 屬性建立響應資料。如果 detail 是列表或字典,則直接使用;否則,將其包裝在一個字典中
if isinstance(exc.detail, (list, dict)):
data = exc.detail
else:
data = {'detail': exc.detail}
# 呼叫 set_rollback() 來確保資料庫回滾(如果有的話)
# set_rollback(): 這個函式用於確保資料庫事務回滾,以防異常發生在資料庫事務內部。
set_rollback()
# 返回一個DRF響應物件
return Response(data, status=exc.status_code, headers=headers)
return None
【四】DRF的異常型別原始碼分析
def _get_error_details(data, default_code=None):
"""
# 將巢狀的資料結構中的潛在翻譯字串或字串轉換為 ErrorDetail 物件。
Descend into a nested data structure, forcing any
lazy translation strings or strings into `ErrorDetail`.
"""
# 處理列表或元組型別的資料。
# 如果資料是列表或元組,它會迭代其中的每個元素
if isinstance(data, (list, tuple)):
# 遞迴呼叫 _get_error_details 函式來處理每個元素,並將結果儲存在 ret 列表中。
ret = [
_get_error_details(item, default_code) for item in data
]
# 如果原始資料是 ReturnList 型別(DRF中的特殊列表型別),則將結果包裝在一個新的 ReturnList 物件中;
if isinstance(data, ReturnList):
# 否則,直接返回 ret 列表。
return ReturnList(ret, serializer=data.serializer)
return ret
# 如果資料是字典,它會迭代其中的每個鍵值對
elif isinstance(data, dict):
# 遞迴呼叫 _get_error_details 函式來處理每個值,並將結果儲存在 ret 字典中。
ret = {
key: _get_error_details(value, default_code)
for key, value in data.items()
}
# 如果原始資料是 ReturnDict 型別(DRF中的特殊字典型別)
if isinstance(data, ReturnDict):
# ,則將結果包裝在一個新的 ReturnDict 物件中
return ReturnDict(ret, serializer=data.serializer)
# 否則,直接返回 ret 字典
return ret
# 如果資料既不是列表/元組也不是字典,那麼它被視為文字資料。
# 這裡使用 force_str 函式將資料強制轉換為字串,然後檢查是否存在 code 屬性。
# 如果存在 code 屬性,將其作為錯誤程式碼;
# 否則,使用 default_code。
# 然後,建立一個 ErrorDetail 物件,其中包含文字和錯誤程式碼,並將其返回。
text = force_str(data)
code = getattr(data, 'code', default_code)
return ErrorDetail(text, code)
# 獲取異常詳細資訊中的錯誤程式碼,以便在響應中提供錯誤資訊的標識。
def _get_codes(detail):
# 引數 detail,該引數可以是任何資料型別(通常是巢狀的錯誤詳細資訊)。
# 函式首先檢查 detail 是否為列表
# 如果是列表,則遞迴呼叫 _get_codes 函式處理列表中的每個元素。
if isinstance(detail, list):
return [_get_codes(item) for item in detail]
# 如果 detail 是字典,則遞迴呼叫 _get_codes 函式處理字典中的每個值。
elif isinstance(detail, dict):
return {key: _get_codes(value) for key, value in detail.items()}
# 最終,如果 detail 不是列表或字典,而是具有 code 屬性的物件,就返回該物件的 code 屬性。
return detail.code
# 獲取異常詳細資訊的完整內容,以便在響應中提供詳細的錯誤資訊和錯誤程式碼。
def _get_full_details(detail):
# 引數 detail,該引數可以是任何資料型別(通常是巢狀的錯誤詳細資訊)。
# 函式首先檢查 detail 是否為列表,如果是列表,則遞迴呼叫 _get_full_details 函式處理列表中的每個元素。
if isinstance(detail, list):
return [_get_full_details(item) for item in detail]
elif isinstance(detail, dict):
# 如果 detail 是字典,則遞迴呼叫 _get_full_details 函式處理字典中的每個值。
return {key: _get_full_details(value) for key, value in detail.items()}
# 最終,如果 detail 不是列表或字典,而是具有 code 屬性的物件,就建立一個包含 message 和 code 的字典並返回。
return {
'message': detail,
'code': detail.code
}
# 用於表示API異常的詳細資訊
class ErrorDetail(str):
"""
A string-like object that can additionally have a code.
"""
# 用於儲存錯誤程式碼,預設為 None。
code = None
# 類的建構函式,它在物件建立時被呼叫。
# 它接受兩個引數:string 是字串的內容,code 是錯誤程式碼。
def __new__(cls, string, code=None):
# 它使用 super().__new__(cls, string) 來建立一個新的字串物件
self = super().__new__(cls, string)
# 並將錯誤程式碼賦值給 self.code。最後,它返回新建立的物件。
self.code = code
return self
# 物件的等於(==)運算子的過載方法。
def __eq__(self, other):
result = super().__eq__(other)
# 它用於比較兩個 ErrorDetail 物件是否相等。
if result is NotImplemented:
return NotImplemented
try:
# 如果兩個物件的內容相等並且它們的錯誤程式碼也相等,返回 True;否則,返回 False。
return result and self.code == other.code
except AttributeError:
return result
# 物件的不等於(!=)運算子的過載方法。
def __ne__(self, other):
# 它使用 __eq__ 方法來實現不等於運算子。
result = self.__eq__(other)
if result is NotImplemented:
return NotImplemented
return not result
# 物件的字串表示方法,用於返回物件的可列印字串表示。
# 它返回一個格式化的字串,包含了字串內容和錯誤程式碼。
def __repr__(self):
return 'ErrorDetail(string=%r, code=%r)' % (
str(self),
self.code,
)
# 物件的雜湊方法,用於生成物件的雜湊值。
# 它基於字串內容的雜湊值生成物件的雜湊值。
def __hash__(self):
return hash(str(self))
# 這個類是所有DRF異常的基類,其他自定義異常應該從這個類繼承,並提供特定的 status_code 和 default_detail 屬性
class APIException(Exception):
"""
Base class for REST framework exceptions.
Subclasses should provide `.status_code` and `.default_detail` properties.
"""
# 這個屬性指定了預設的HTTP狀態程式碼,如果子類沒有提供自定義的 status_code,則預設為500(內部伺服器錯誤)。
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
# 這個屬性指定了預設的異常詳細資訊,它是一個本地化字串,用於描述異常的內容。
# 在這裡,使用了 _() 函式來標記該字串以進行國際化/本地化處理。
default_detail = _('A server error occurred.')
# 這個屬性指定了預設的錯誤程式碼,用於標識異常型別。預設為 'error'。
default_code = 'error'
# 類的建構函式,它接受兩個可選引數:detail 和 code
def __init__(self, detail=None, code=None):
# 建構函式首先檢查這兩個引數是否為 None
# 如果是,就將它們設定為預設值(default_detail 和 default_code)。
if detail is None:
detail = self.default_detail
if code is None:
code = self.default_code
# 然後,建構函式呼叫 _get_error_details 函式來處理 detail 和 code,並將結果儲存在 self.detail 屬性中。
self.detail = _get_error_details(detail, code)
def __str__(self):
# 返回異常的字串表示,通常是異常詳細資訊的字串表示。
return str(self.detail)
# 獲取異常詳細資訊中的錯誤程式碼。
def get_codes(self):
"""
Return only the code part of the error details.
Eg. {"name": ["required"]}
"""
# 它呼叫 _get_codes 函式來處理 self.detail,並返回結果。
return _get_codes(self.detail)
# 獲取異常詳細資訊的完整內容,包括訊息和錯誤程式碼。
def get_full_details(self):
"""
Return both the message & code parts of the error details.
Eg. {"name": [{"message": "This field is required.", "code": "required"}]}
"""
# 它呼叫 _get_full_details 函式來處理 self.detail,並返回結果。
return _get_full_details(self.detail)
# 用於表示API請求中的驗證錯誤,通常與HTTP 400 Bad Request狀態一起使用。
class ValidationError(APIException):
# 這個屬性指定了 HTTP 400 Bad Request 狀態程式碼,表示請求的內容或引數不符合要求。
status_code = status.HTTP_400_BAD_REQUEST
# 這個屬性指定了預設的異常詳細資訊,用於描述驗證失敗的原因。它是一個本地化字串,通常為 "Invalid input."。
default_detail = _('Invalid input.')
# 這個屬性指定了預設的錯誤程式碼,用於標識驗證失敗。預設為 'invalid'。
default_code = 'invalid'
# 類的建構函式,它接受兩個可選引數:detail 和 code。
def __init__(self, detail=None, code=None):
# 檢查這兩個引數是否為 None
# 如果是,就將它們設定為預設值(default_detail 和 default_code)。
if detail is None:
detail = self.default_detail
if code is None:
code = self.default_code
# For validation failures, we may collect many errors together,
# so the details should always be coerced to a list if not already.
# 然後,建構函式檢查 detail 是否為元組
# 如果是,將其轉換為列表;
if isinstance(detail, tuple):
detail = list(detail)
# 如果 detail 既不是字典也不是列表,將其包裝成一個列表。
elif not isinstance(detail, dict) and not isinstance(detail, list):
detail = [detail]
# 最後,建構函式呼叫 _get_error_details 函式來處理 detail 和 code,並將結果儲存在 self.detail 屬性中。
self.detail = _get_error_details(detail, code)
# 表示解析請求時出現錯誤,通常對應HTTP 400 Bad Request狀態。
# 預設詳細資訊為 "Malformed request."。
class ParseError(APIException):
status_code = status.HTTP_400_BAD_REQUEST
default_detail = _('Malformed request.')
default_code = 'parse_error'
# 表示身份驗證失敗,通常對應HTTP 401 Unauthorized狀態。
# 預設詳細資訊為 "Incorrect authentication credentials."。
class AuthenticationFailed(APIException):
status_code = status.HTTP_401_UNAUTHORIZED
default_detail = _('Incorrect authentication credentials.')
default_code = 'authentication_failed'
# 表示未提供身份驗證憑據,通常對應HTTP 401 Unauthorized狀態。
# 預設詳細資訊為 "Authentication credentials were not provided."。
class NotAuthenticated(APIException):
status_code = status.HTTP_401_UNAUTHORIZED
default_detail = _('Authentication credentials were not provided.')
default_code = 'not_authenticated'
# 表示沒有執行此操作的許可權,通常對應HTTP 403 Forbidden狀態。
# 預設詳細資訊為 "You do not have permission to perform this action."。
class PermissionDenied(APIException):
status_code = status.HTTP_403_FORBIDDEN
default_detail = _('You do not have permission to perform this action.')
default_code = 'permission_denied'
# 表示資源未找到,通常對應HTTP 404 Not Found狀態。
# 預設詳細資訊為 "Not found."。
class NotFound(APIException):
status_code = status.HTTP_404_NOT_FOUND
default_detail = _('Not found.')
default_code = 'not_found'
# 表示請求的HTTP方法不允許,通常對應HTTP 405 Method Not Allowed狀態。它包括一個額外的引數 method,用於指定不允許的HTTP方法。
# 預設詳細資訊為 "Method "{method}" not allowed."。
class MethodNotAllowed(APIException):
status_code = status.HTTP_405_METHOD_NOT_ALLOWED
default_detail = _('Method "{method}" not allowed.')
default_code = 'method_not_allowed'
def __init__(self, method, detail=None, code=None):
if detail is None:
detail = force_str(self.default_detail).format(method=method)
super().__init__(detail, code)
# 表示無法滿足請求的Accept頭部,通常對應HTTP 406 Not Acceptable狀態。
# 它包括一個額外的引數 available_renderers,用於指定可用的渲染器。
# 預設詳細資訊為 "Could not satisfy the request Accept header."。
class NotAcceptable(APIException):
status_code = status.HTTP_406_NOT_ACCEPTABLE
default_detail = _('Could not satisfy the request Accept header.')
default_code = 'not_acceptable'
def __init__(self, detail=None, code=None, available_renderers=None):
self.available_renderers = available_renderers
super().__init__(detail, code)
# 表示請求中包含了不支援的媒體型別(Media Type),通常對應HTTP 415 Unsupported Media Type狀態。
# 它包括一個額外的引數 media_type,用於指定不支援的媒體型別。
# 預設詳細資訊為 "Unsupported media type "{media_type}" in request."。
class UnsupportedMediaType(APIException):
status_code = status.HTTP_415_UNSUPPORTED_MEDIA_TYPE
default_detail = _('Unsupported media type "{media_type}" in request.')
default_code = 'unsupported_media_type'
def __init__(self, media_type, detail=None, code=None):
if detail is None:
detail = force_str(self.default_detail).format(media_type=media_type)
super().__init__(detail, code)
# 表示請求被限速(Throttled),通常對應HTTP 429 Too Many Requests狀態。
# 它包括一個額外的引數 wait,用於指定還需等待多少時間才能再次進行請求。
# 預設詳細資訊為 "Request was throttled.",並且根據 wait 引數動態生成額外的詳細資訊,用於描述還需等待的時間。
class Throttled(APIException):
status_code = status.HTTP_429_TOO_MANY_REQUESTS
default_detail = _('Request was throttled.')
extra_detail_singular = _('Expected available in {wait} second.')
extra_detail_plural = _('Expected available in {wait} seconds.')
default_code = 'throttled'
def __init__(self, wait=None, detail=None, code=None):
if detail is None:
detail = force_str(self.default_detail)
if wait is not None:
wait = math.ceil(wait)
detail = ' '.join((
detail,
force_str(ngettext(self.extra_detail_singular.format(wait=wait),
self.extra_detail_plural.format(wait=wait),
wait))))
self.wait = wait
super().__init__(detail, code)
# 這個函式是用於處理通用的伺服器錯誤,通常對應HTTP 500 Internal Server Error狀態。
# 當伺服器發生未處理的異常時,Django會呼叫這個檢視函式。該函式返回一個JSON響應,其中包含一個簡單的錯誤訊息,狀態程式碼為HTTP 500。
def server_error(request, *args, **kwargs):
"""
Generic 500 error handler.
"""
data = {
'error': 'Server Error (500)'
}
return JsonResponse(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# 這個函式是用於處理通用的客戶端請求錯誤,通常對應HTTP 400 Bad Request狀態。
# 當Django無法處理客戶端請求時(例如,請求的資料格式不正確),或者檢視中丟擲了 ValidationError 異常時,Django會呼叫這個檢視函式。
# 該函式返回一個JSON響應,其中包含一個簡單的錯誤訊息,狀態程式碼為HTTP 400。
def bad_request(request, exception, *args, **kwargs):
"""
Generic 400 error handler.
"""
data = {
'error': 'Bad Request (400)'
}
return JsonResponse(data, status=status.HTTP_400_BAD_REQUEST)
【五】自定義異常捕獲類
from rest_framework.views import exception_handler
from rest_framework.response import Response
from .common_logger import logger
# 日誌記錄必要的報錯資訊
# 記錄日誌資訊必含:使用者地址 + 使用者ID + 請求地址 + 執行的檢視函式 + 異常原因
def common_exception_handler(exc, context):
# 獲取請求物件
request = context.get('request')
# 獲取檢視物件
view = context.get('view')
# 獲取請求的IP地址
ip = request.META.get('REMOTE_ADDR')
try:
# 嘗試獲取使用者ID,如果使用者未登入,則設定為"未登入使用者"
user_id = request.user.id
except:
user_id = "未登入使用者"
# 獲取請求的完整路徑
path = request.get_full_path()
# 將檢視物件轉換為字串以記錄日誌
view_str = str(view)
# 呼叫預設異常處理函式獲取異常響應
res = exception_handler(exc, context)
# 構建錯誤日誌資訊
error = f'當前使用者地址 : {ip} , 使用者ID : {user_id} , 請求地址 : {path} , 執行的檢視函式 {view_str} , 異常原因 : {str(exc)}'
# 使用日誌記錄器記錄錯誤日誌
logger.error(error)
if res:
# 如果存在異常響應
if isinstance(res.data, dict):
# 如果異常響應的資料是字典型別,一般是DRF的異常
# DRF 異常:一種是從 res.data 中取/一種是從 data 中取
data = {"code": 999, "msg": res.data.get("detail", "系統錯誤,請聯絡管理員")}
else:
# 如果異常響應的資料不是字典型別,通常是其他異常
data = {"code": 888, "msg": str(exc)}
# 返回自定義的異常響應
return Response(data)
【六】DRF自帶的響應狀態碼
from rest_framework import status
# 判斷給定的HTTP狀態碼是否屬於資訊性狀態碼,資訊性狀態碼的範圍是100到199。
def is_informational(code):
return 100 <= code <= 199
# 判斷給定的HTTP狀態碼是否屬於成功狀態碼,成功狀態碼的範圍是200到299。
def is_success(code):
return 200 <= code <= 299
# 判斷給定的HTTP狀態碼是否屬於重定向狀態碼,重定向狀態碼的範圍是300到399。
def is_redirect(code):
return 300 <= code <= 399
# 判斷給定的HTTP狀態碼是否屬於客戶端錯誤狀態碼,客戶端錯誤狀態碼的範圍是400到499。
def is_client_error(code):
return 400 <= code <= 499
# 判斷給定的HTTP狀態碼是否屬於伺服器錯誤狀態碼,伺服器錯誤狀態碼的範圍是500到599。
def is_server_error(code):
return 500 <= code <= 599
# 1xx(資訊性狀態碼)表示請求已被接受,繼續處理。
# 繼續。伺服器僅接受客戶端請求的一部分,等待客戶端繼續傳送請求。
HTTP_100_CONTINUE = 100
# 切換協議。伺服器將遵從客戶的請求切換協議。
HTTP_101_SWITCHING_PROTOCOLS = 101
# 處理中。伺服器正在處理請求,但需要更多時間。
HTTP_102_PROCESSING = 102
# 提前提示。伺服器可以將頭資訊返回給客戶端,以提前表示響應可能的形式。
HTTP_103_EARLY_HINTS = 103
# 2xx(成功狀態碼)表示請求已成功接收、理解、接受。
# OK。請求已成功,請求所希望的響應頭或資料體將隨此響應返回。
HTTP_200_OK = 200
# 已建立。請求已經被實現,而且有一個新的資源已經依據請求的需要而建立。
HTTP_201_CREATED = 201
# 已接受。伺服器已接受請求,但尚未處理。
HTTP_202_ACCEPTED = 202
# 非授權資訊。伺服器已成功處理了請求,但返回的資訊可能來自另一來源。
HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203
# 無內容。伺服器成功處理了請求,但沒有返回任何內容。
HTTP_204_NO_CONTENT = 204
# 重置內容。伺服器成功處理了請求,使用者代理必須重置文件檢視。
HTTP_205_RESET_CONTENT = 205
# 部分內容。伺服器已經成功處理了部分 GET 請求。
HTTP_206_PARTIAL_CONTENT = 206
# 多狀態。XML 資料包含可執行的多個狀態。
HTTP_207_MULTI_STATUS = 207
# 已報告。資源已在之前的請求中報告,返回的響應應該是被引用資源的當前狀態。
HTTP_208_ALREADY_REPORTED = 208
# IM Used。伺服器已經滿足了對資源的請求,響應是對實體(如 HTML 頁面或 JSON 檔案)的表示。
HTTP_226_IM_USED = 226
# 3xx(重定向狀態碼)表示客戶必須採取進一步的操作才能完成請求。
# 多種選擇。被請求的資源存在多種可供選擇的響應。
HTTP_300_MULTIPLE_CHOICES = 300
# 永久移動。請求的資源已被永久移動到新 URI。
HTTP_301_MOVED_PERMANENTLY = 301
# 找到。請求的資源現在臨時從不同的 URI 響應請求。
HTTP_302_FOUND = 302
# 參見其他。對應當前請求的響應可以在另一個 URI 上被找到。
HTTP_303_SEE_OTHER = 303
# 未修改。自從上次請求後,請求的資源未被修改過。
HTTP_304_NOT_MODIFIED = 304
# 使用代理。請求的資源必須透過指定的代理才能被訪問。
HTTP_305_USE_PROXY = 305
# 保留。該狀態碼將被任何操作繼續執行之前,需要客戶端的進一步操作來完成請求。
HTTP_306_RESERVED = 306
# 臨時重定向。請求的資源現在臨時從不同的 URI 響應請求。
HTTP_307_TEMPORARY_REDIRECT = 307
# 永久重定向。請求的資源已被永久移動到新 URI。
HTTP_308_PERMANENT_REDIRECT = 308
# 4xx(客戶端錯誤狀態碼)表示客戶端看起來可能發生了錯誤。
# 錯誤請求。伺服器不理解請求的語法。
HTTP_400_BAD_REQUEST = 400
# 未授權。請求要求身份驗證。
HTTP_401_UNAUTHORIZED = 401
# 需要付款。保留供將來使用。
HTTP_402_PAYMENT_REQUIRED = 402
# 禁止。伺服器拒絕請求。
HTTP_403_FORBIDDEN = 403
# 未找到。伺服器找不到請求的資源。
HTTP_404_NOT_FOUND = 404
# 方法不允許。請求中指定的方法不被允許。
HTTP_405_METHOD_NOT_ALLOWED = 405
# 不可接受。伺服器只生成不可接受的響應。
HTTP_406_NOT_ACCEPTABLE = 406
# 需要代理身份驗證。客戶端必須先使用代理認證。
HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407
# 請求超時。伺服器等候請求時發生超時。
HTTP_408_REQUEST_TIMEOUT = 408
# 衝突。請求在當前資源狀態下無法執行。
HTTP_409_CONFLICT = 409
# 消失。請求的資源已被永久刪除。
HTTP_410_GONE = 410
# 需要長度。伺服器拒絕在沒有定義 Content-Length 頭的情況下接受請求。
HTTP_411_LENGTH_REQUIRED = 411
# 前提條件不滿足。請求中給定的前提條件由伺服器評估為 false。
HTTP_412_PRECONDITION_FAILED = 412
# 請求實體過大。伺服器拒絕處理請求,因為請求實體過大。
HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413
# 請求 URI 過長。伺服器拒絕提供服務,因為請求的 URI 過長。
HTTP_414_REQUEST_URI_TOO_LONG = 414
# 不支援的媒體型別。伺服器拒絕處理不支援的媒體型別的請求。
HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415
# 請求範圍不符合要求。頁面無法提供請求的範圍。
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416
# 期望失敗。伺服器未滿足"期望"請求標頭欄位的要求。
HTTP_417_EXPECTATION_FAILED = 417
# 我是茶壺。伺服器拒絕嘗試用它不會被燒水的茶壺做咖啡。
HTTP_418_IM_A_TEAPOT = 418
# 誤導的請求。請求指向了伺服器上不存在的資源。
HTTP_421_MISDIRECTED_REQUEST = 421
# 不可處理的實體。請求格式正確,但由於語義錯誤而無法滿足。
HTTP_422_UNPROCESSABLE_ENTITY = 422
# 已鎖定。當前資源被鎖定。
HTTP_423_LOCKED = 423
# 依賴失敗。由於之前的請求失敗,所以此次請求失敗。
HTTP_424_FAILED_DEPENDENCY = 424
# 過早。伺服器不願意冒著風險去處理可能重播的請求。
HTTP_425_TOO_EARLY = 425
# 需要升級。客戶端應切換到TLS/1.0。
HTTP_426_UPGRADE_REQUIRED = 426
# 先決條件要求。要求先決條件,而請求未滿足。
HTTP_428_PRECONDITION_REQUIRED = 428
# 請求過多。使用者在給定的時間內傳送了太多請求。
HTTP_429_TOO_MANY_REQUESTS = 429
# 請求頭欄位太大。伺服器不願意處理請求,因為請求頭欄位太大。
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431
# 因法律原因不可用。訪問資源受到法律限制。
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451
# 5xx(伺服器錯誤狀態碼)表示伺服器在嘗試處理請求時發生錯誤。
# 內部伺服器錯誤。伺服器遇到錯誤,無法完成請求。
HTTP_500_INTERNAL_SERVER_ERROR = 500
# 未實現。伺服器不具備完成請求的功能。
HTTP_501_NOT_IMPLEMENTED = 501
# 錯誤閘道器。伺服器作為閘道器或代理,從上游伺服器收到了無效的響應。
HTTP_502_BAD_GATEWAY = 502
# 服務不可用。伺服器目前無法提供請求所需的服務。
HTTP_503_SERVICE_UNAVAILABLE = 503
# 閘道器超時。伺服器作為閘道器或代理,未及時從上游伺服器接收請求。
HTTP_504_GATEWAY_TIMEOUT = 504
# HTTP 版本不受支援。伺服器不支援請求中所用的 HTTP 協議版本。
HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505
# 內容協商。伺服器存在內部配置問題。
HTTP_506_VARIANT_ALSO_NEGOTIATES = 506
# 儲存不足。伺服器無法儲存完成請求所必須的內容。
HTTP_507_INSUFFICIENT_STORAGE = 507
# 檢測到迴圈。伺服器檢測到無限迴圈。
HTTP_508_LOOP_DETECTED = 508
# 超出頻寬限制。伺服器達到頻寬限制。
HTTP_509_BANDWIDTH_LIMIT_EXCEEDED = 509
# 擴充套件未執行。客戶端需要進一步執行操作以完成請求。
HTTP_510_NOT_EXTENDED = 510
# 需要網路認證。客戶端需要進行網路身份驗證才能獲得請求的響應。
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511