django rest-framework 自定义异常捕获类

环境: django 3.2 python3

先创建文件exceptions.py(文件名称可以自定义)

1、重写exception_handler, 自定义异常类

# -*- coding: utf-8 -*-
"""
MyException: 自定义异常捕获类(可以继续补充完整)
"""
import traceback
from rest_framework.exceptions import ValidationError
from rest_framework.views import exception_handler
from django.db import DatabaseError
from pymongo.errors import PyMongoError
from rest_framework.response import Response


def MyException(exc, context):
    """
    自定义异常捕获类
    """
    print(traceback.format_exc())
    print(exc, "========", context)
    response = exception_handler(exc, context)
    print(response)
    print(response.__dict__)
    # drf 内部未知错误
    if response is None:
        # view = context["view"]
        if isinstance(exc, DatabaseError) or isinstance(exc, PyMongoError):
            response = Response({"code": "", "message": "数据库异常"})
        else:
            # todo 这里不友好,异常时无法判定错误原因,可以详细打印错误内容(traceback)
            response = Response({"code": "", "message": "服务器未知错误"})
    # drf 内部已知错误
    else:
        # 方式一 http状态码作为code,错误信息作为message直接返回
        # 如果序列化出错时,错误信息字段为non_field_errors,类型为列表,其他错误信息字段为detail,类型字符串
        response.data['message'] = response.data.pop('detail') if response.data.get('detail') else '/'.join(response.data.pop('non_field_errors'))
        response.data["code"] = response.status_code
        # 方式二根据http状态码返回自定义code,错误信息自定义
        # status_code = response.status_code
        # if response.data.get("detail"):
        #     del response.data["detail"]
        # if response.data.get("non_field_errors"):
        #     del response.data["non_field_errors"]
        # if status_code == 404:
        #     response.data["code"] = ""
        #     # response.data["message"] = "未找到"
        # elif status_code == 400:
        #     response.data["code"] = ""
        #     # response.data["message"] = "错误请求"
        # elif status_code == 401:
        #     response.data["code"] = ""
        #     # response.data["message"] = "未认证"
        # elif status_code >= 500:
        #     response.data["code"] = ""
        #     # response.data["message"] = "服务器错误"
        # elif status_code == 403:
        #     response.data["code"] = ""
        #     # response.data["message"] = "权限不允许"
        # elif status_code == 405:
        #     response.data["code"] = ""
        #     # response.data["message"] = "请求不允许"
        # else:
        #     response.data["code"] = ""
        #     # response.data["message"] = "未知错误"
    return response

自定义异常中参数说明:

def MyException(exc, context):
    response = exception_handler(exc, context)
    print(response.__dict__)
	......

exc: 错误信息,相当于try...exception Exception as e中 e 对应的值
context: 错误信息,其中报错一些视图路由信息
response:如果错误是drf内部定义的则返回Response对象,否则返回None。
response.__dict__: response对象内部属性方法

参数各值示例

{
    "exc": "jwt_authentication_expire",
    "context": {"view": <create_task.views.UploadFile object at 0x0000027CE4EC7DD8>, "args": (), "kwargs": {}, "request": <rest_framework.request.Request: GET "/create_task/upload_file_or_id/">},
	"response":<Response status_code=403, "text/html; charset=utf-8">,
	"response.__dict__":{"template_name": None, "context_data": None, "using": None, "_post_render_callbacks": [], "_request": None, "_headers": {"content-type": ("Content-Type", "text/html; charset=utf-8")}, "_closable_objects": [], "_handler_class": None, "cookies": <SimpleCookie: >, "closed": False, "status_code": 403, "_reason_phrase": None, "_charset": None, "_container": [b""], "_is_rendered": False, "data": {"detail": ErrorDetail(string="jwt_authentication_expire", code="authentication_failed")}, "exception": False, "content_type": None}
}

2、settings.py中增加配置

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'utils.exceptions.MyException',
}

在自定义异常中,可以使用traceback.format_exc()来获取异常信息的详细情况,同样也可以将详细报错信息写入日志,方便排查。

至此就大功告成,如有问题还请指出~~

posted @   不懂开发的程序猿!  阅读(180)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示