drf关于异常的捕获处理

版权声明:内容版权为CSDN用户:kayseen 所有,若您需要引用、转载,需要注明来源及原文链接 https://blog.csdn.net/m0_43394876/article/details/88581870

情景分析:
在以前的项目中,我们每处理一次数据库操作,就要使用try except来捕获数据库异常并且记录日志,这个异常不是数据库语法的异常,而是数据库的连接之类的异常


有两个特殊情况需要特殊处理使用try except:
①查询的数据不存在②增加的数据已经存在


其他的普通异常如果没有try except,那么会交给APIView来处理,任何APIException异常都会被它捕获到,并且处理成合适的响应信息,返回给from rest_framework.views import exception_handler这个包里面的response = exception_handler(exc, context)来处理。
包括视图扩展类(CreateModelMixin)的源码里面也会有serializer.is_valid(raise_exception=True)来检验数据,它也没有try except来处理异常,就会把异常也往上抛给exception_handler处理;
反序列化的校验字段也会抛出异常raise serializers.ValidationError,这个异常也是抛给exception_handler来处理


但是exception_handler默认不会处理数据库的异常,所以我们就重写该方法补充该功能。
新建utils/exceptions.py

from rest_framework.views import exception_handler as drf_exception_handler
import logging
from rest_framework.response import Response
from rest_framework import status
#所有的数据库异常都是这两个异常的儿子或孙子,导入他俩就行
from django.db import DatabaseError
from redis.exceptions import RedisError

# 获取在配置文件中定义的logger,用来记录日志
logger = logging.getLogger('django')

def exception_handler(exc, context):
    """
    自定义异常处理
    :param exc: 别的地方抛的异常就会传给exc
    :param context: 字典形式。抛出异常的上下文(即抛出异常的出处;即抛出异常的视图)
    :return: Response响应对象
    """
    # 调用drf框架原生的异常处理方法,把异常和异常出处交给他处理,如果是序列化器异常就直接处理,处理之后就直接返回
    response = drf_exception_handler(exc, context)
	#如果响应为空表示不是序列化器异常,补充数据库异常
    if response is None:
        view = context['view']
        if isinstance(exc, DatabaseError) or isinstance(exc, RedisError):
            # 数据库异常
            logger.error('[%s] %s' % (view, exc))
            response = Response({'message': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)

    return response

猜你喜欢

转载自blog.csdn.net/m0_43394876/article/details/88581870