• drf


    异常部分源码分析

    1. 在rest_framework.views的dispath方法中

    def dispatch(self, request, *args, **kwargs):
        """
        `.dispatch()` is pretty much the same as Django's regular dispatch,
        but with extra hooks for startup, finalize, and exception handling.
        """
        self.args = args
        self.kwargs = kwargs
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?
    
        try:
            # 三大验证
            self.initial(request, *args, **kwargs)
    
            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
    
            response = handler(request, *args, **kwargs)
    
        except Exception as exc:
            response = self.handle_exception(exc)  # 捕获万能异常并处理
    
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response
    

    2.有异常时,调用 handle_exception 方法

    def handle_exception(self, exc):
        """
        Handle any exception that occurs, by returning an appropriate response,
        or re-raising the error.
        """
        # 处理认证失败异常
        if isinstance(exc, (exceptions.NotAuthenticated,
                            exceptions.AuthenticationFailed)):
            # WWW-Authenticate header for 401 responses, else coerce to 403
            auth_header = self.get_authenticate_header(self.request)
    
            if auth_header:
                exc.auth_header = auth_header
            else:
                exc.status_code = status.HTTP_403_FORBIDDEN
        # 获取异常句柄
        exception_handler = self.get_exception_handler()  # self.settings.EXCEPTION_HANDLER,默认指向 rest_framework.views.exception_handler函数
    
        context = self.get_exception_handler_context()  # 获取异常处理的内容
        response = exception_handler(exc, context)  # 调用exception_handler方法处理异常
        # 如果response为None,则是exception_handler中未捕获到的异常
        if response is None:
            self.raise_uncaught_exception(exc)
    
        response.exception = True
        return response
    

    3.调用 exception_handler 方法处理异常

    def exception_handler(exc, context):
        # Http404异常处理
        if isinstance(exc, Http404):
            exc = exceptions.NotFound()
        # PermissionDenied权限异常处理
        elif isinstance(exc, PermissionDenied):
            exc = exceptions.PermissionDenied()
        # APIException异常处理
        if isinstance(exc, exceptions.APIException):
            headers = {}
            if getattr(exc, 'auth_header', None):
                headers['WWW-Authenticate'] = exc.auth_header
            if getattr(exc, 'wait', None):
                headers['Retry-After'] = '%d' % exc.wait
    
            if isinstance(exc.detail, (list, dict)):
                data = exc.detail
            else:
                data = {'detail': exc.detail}
    
            set_rollback()
            return Response(data, status=exc.status_code, headers=headers)
        # 未捕获到的异常,返回None
        return None
    

    自定义异常处理

    可见如果需要自定义异常处理,只需要重写exception_handler 方法。将exception_handler指向我们所写的 exception_handler 方法

    setting.py文件添加配置

    REST_FRAMEWORK = {
        'EXCEPTION_HANDLER': 'apis.exceptions.exception_handler',
    }
    

    exceptions.py文件重写exception_handler方法

    from rest_framework.response import Response
    from rest_framework.views import exception_handler as drf_exception_handler
    def exception_handler(exc,context):
        # drf的异常还是提交给 drf_exception_handler,我们只需要处理drf未处理的异常
        response = drf_exception_handler(exc,context)
    
        if response is None:
            # drf 处理不了的异常
            # 可以在此通过 logging 记录异常日志
            return Response({
                'exception':'服务器异常'
            }, status=500)
    
        response.exception = True
        return response
    
  • 相关阅读:
    第八周进度条
    对老师的评价
    构建之法阅读笔记03
    构建之法阅读笔记02
    第七周进度条
    团队冲刺第二周07
    团队冲刺第二周06
    Java jdbc 连接oracle
    Java 生成验证码
    Oracle 触发器的简单命令
  • 原文地址:https://www.cnblogs.com/863652104kai/p/11523953.html
Copyright © 2020-2023  润新知