DRF之异常捕获源码分析
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
本文作者:ssrheart
本文链接:https://www.cnblogs.com/ssrheart/p/18153603
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步