当前位置:   article > 正文

Django Rest Framework 全局异常处理_django全局异常处理

django全局异常处理

在这里插入图片描述

Django Rest Framework(DRF)中,全局异常处理是一种重要的机制,它可以帮助我们更好地管理API中的异常情况,并返回统一的错误响应。本文将详细介绍两种全局异常处理的方法:使用中间件(Middleware)和使用DRF内置的异常处理机制(ExceptionHandler)。

1. 使用中间件进行异常处理

中间件是Django中的一个通用概念,它可以用于全局性的请求和响应处理。我们可以通过自定义中间件来捕获API请求中的异常,并返回统一的错误响应。

步骤1:配置中间件

首先,在项目的settings.py文件中添加我们自定义的异常处理中间件。

# settings.py
MIDDLEWARE = [
    # ...
    # 异常处理中间件
    'utils.middleware.ExceptionMiddleware',
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
'
运行

步骤2:自定义中间件

然后,在utils/middleware.py文件中定义我们的异常处理中间件。

# utils/middleware.py
import logging
from django.db import DatabaseError
from django.http.response import JsonResponse
from django.http import HttpResponseServerError
from django.middleware.common import MiddlewareMixin
from rest_framework import status
from rest_framework.response import Response
from utils.enums import *
from utils.exceptions import *
from utils.result import R
logger = logging.getLogger('django')
class ExceptionMiddleware(MiddlewareMixin):
    """统一异常处理中间件"""
    def process_exception(self, request, exception):
        """
        统一异常处理
        :param request: 请求对象
        :param exception: 异常对象
        :return:
        """
        if isinstance(exception, BusinessException):
            # 业务异常处理
            data = R.set_result(exception.enum_cls).data()
            return JsonResponse(data)
        elif isinstance(exception, DatabaseError):
            # 数据库异常
            r = R.set_result(StatusCodeEnum.DB_ERR)
            logger.error(r.data(), exc_info=True)
            return HttpResponseServerError(StatusCodeEnum.SERVER_ERR.errmsg)
        elif isinstance(exception, Exception):
            # 服务器异常处理
            r = R.server_error()
            logger.error(r.data(), exc_info=True)
            return HttpResponseServerError(r.errmsg)
        return None
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

步骤3:自定义异常类和状态码枚举

utils/exceptions.pyutils/enums.py文件中,我们可以定义自己的异常类和状态码枚举类。

# utils/exceptions.py
class CommonException(Exception):
    """公共异常类"""
    def __init__(self, enum_cls):
        self.code = enum_cls.code
        self.errmsg = enum_cls.errmsg
        self.enum_cls = enum_cls  # 状态码枚举类
        super().__init__()
class BusinessException(CommonException):
    """业务异常类"""
    pass
class APIException(CommonException):
    """接口异常类"""
    pass
# utils/enums.py
class StatusCodeEnum(Enum):
    """状态码枚举类"""
    OK = (0, '成功')
    ERROR = (-1, '错误')
    SERVER_ERR = (500, '服务器异常')
    # ... 其他状态码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

步骤4:响应信息封装

utils/result.py文件中,我们可以定义一个统一项目信息返回结果类。

# utils/result.py
class R(object):
    """
    统一项目信息返回结果类
    """
    def __init__(self):
        self.code = None
        self.errmsg = None
        self._data = dict()
    @staticmethod
    def ok():
        """
        组织成功响应信息
        :return:
        """
        r = R()
        r.code = StatusCodeEnum.OK.code
        r.errmsg = StatusCodeEnum.OK.errmsg
        return r
    @staticmethod
    def error():
        """
        组织错误响应信息
        :return:
        """
        r = R()
        r.code = StatusCodeEnum.ERROR.code
        r.errmsg = StatusCodeEnum.ERROR.errmsg
        return r
    @staticmethod
    def server_error():
        """
        组织服务器错误信息
        :return:
        """
        r = R()
        r.code = StatusCodeEnum.SERVER_ERR.code
        r.errmsg = StatusCodeEnum.SERVER_ERR.errmsg
        return r
    @staticmethod
    def set_result(enum):
        """
        组织对应枚举类的响应信息
        :param enum: 状态枚举类
        :return:
        """
        r = R()
        r.code = enum.code
        r.errmsg = enum.errmsg
        return r
    def data(self, key=None, obj=None):
        """统一后端返回的数据"""
        if key:
            self._data[key] = obj
        context = {
            'code': self.code,
            'errmsg': self.errmsg,
            'data':self._data
        }
        return context
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
'
运行

步骤5:测试视图

最后,在视图中抛出我们自定义的异常,以测试我们的异常处理机制是否有效。

# views.py
from rest_framework.decorators import api_view
from rest_framework.views import APIView
from utils.enums import StatusCodeEnum
from utils.exceptions import *
class TestView(APIView):
    @api_view(['POST'])
    def verify_params(request):
        """
        校验注册信息
        :param request: 注册请求对象
        :return: response_ret
        """
        # 接受参数
        params = get_parameter_dic(request)
        username = params.get('username')
        mobile = params.get('mobile')
        # 校验参数
        all_args = [username, mobile]
        if not all(all_args):
            raise BusinessException(StatusCodeEnum.PARAM_ERR)
        # 用户名 5-20个字符
        if not re.match(r'^[a-zA-Z0-9_]{5,20}', username):
            raise BusinessException(StatusCodeEnum.USER_ERR)
        # 手机号合法性
        if not mobile:
            raise BusinessException(StatusCodeEnum.MOBILE_ERR)
        return Response("成功", status=status.HTTP_200_OK)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

2. 使用ExceptionHandler进行异常处理

除了使用中间件,我们还可以使用DRF内置的异常处理机制(ExceptionHandler)来处理API中的异常。

步骤1:自定义异常处理函数

首先,在utils/exceptions.py文件中定义我们的自定义异常处理函数。

# utils/exceptions.py
from rest_framework.views import exception_handler
def custom_exception_handler(exc, context):
    response = exception_handler(exc, context)
    if response is not None:
        response.data['status_code'] = response.status_code
    elif isinstance(exc, Exception):
        response = Response("其它异常")
    return response
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

步骤2:配置ExceptionHandler

然后,在项目的settings.py文件中配置我们自定义的异常处理函数。

# settings.py
REST_FRAMEWORK = {
    # 统一异常处理
    'EXCEPTION_HANDLER': 'utils.exception.custom_exception_handler'
}
  • 1
  • 2
  • 3
  • 4
  • 5
'
运行

这样,当API中发生异常时,就会调用我们自定义的异常处理函数,并返回统一的错误响应。
以上就是在Django Rest Framework中进行全局异常处理的两种方法。我们可以根据项目的具体需求选择合适的方法来实现异常处理。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/979557
推荐阅读
相关标签
  

闽ICP备14008679号