首页 > 编程语言 >全局异常捕获及源码分析

全局异常捕获及源码分析

时间:2024-04-21 22:13:42浏览次数:28  
标签:exception exc handler self request response 源码 全局 捕获

全局异常捕获

​ drf只会捕获属于drf的异常,所以要做到全局异常捕获,还需要手动操作一下。

​ 经过对drf异常处理组件的源码分析之后可以得知,其实就是自己定义一个exception_handler函数,然后全局替换一下即可

​ 首先要知道,虽然是自己写一个exception_handler函数,但是drf的exception_handler也还是有用的,因为drf已经帮我们处理好了,drf的异常,我们只需要处理其他的异常即可

​ 通过读exception_handler文件可知,只要返回的是None,那么该异常不属于drf

from rest_framework.views import exception_handler, APIView
from rest_framework.response import Response


# 自定义异常类
class PasswordException(Exception):
    def __init__(self, msg):
        self.msg = msg


def common_exception_handler(exc, context):
    # 下面这一堆都是获取日志内容的信息
    request = context['request']
    ip = request.META.get('REMOTE_ADDR')
    path = 'http://127.0.0.1:8000' + request.get_full_path()
    method = request.method
    view = context['view']
    user_id = request.user.pk or '游客登录'
    print(f"请求方式:{method},请求地址:{path},访问ip:{ip},出错地址:{view},用户id:{user_id}")

	# 调用drf内置的exception_handler函数
    res = exception_handler(exc, context)
    # 如果没有res,就说明不是drf的报错
    # 所以需要自己处理,正常返回Response对象,做到真正的全局异常捕获
    if not res:
        return Response({'code': 301, 'message': f'自己的问题哦:>>>{str(exc)}'})
    #
    if isinstance(res.data, dict):
        return Response({'code': 302, 'message': f'drf的问题:>>>{res.data.get("detail")}'})
    return Response({'code': 302, 'message': f'drf的问题:>>>{res.data[0]}'})


异常捕获源码解析

# 首先看dispath
# 这里面首先做了三大认证,然后做了异常捕获处理
def dispatch(self, request, *args, **kwargs):
    self.args = args
    self.kwargs = kwargs
    request = self.initialize_request(request, *args, **kwargs)
    self.request = request
    self.headers = self.default_response_headers 
    try:
        # 这一步是在做三大认证
        self.initial(request, *args, **kwargs)
        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:
        # 做了异常捕获
        # 点进handle_exception往下看
        response = self.handle_exception(exc)
		
    self.response = self.finalize_response(request, response, *args, **kwargs)
    return self.response
# 可以看到做了一堆if判断,最后是要返回一个response
def handle_exception(self, exc):

    if isinstance(exc, (exceptions.NotAuthenticated,
                        exceptions.AuthenticationFailed)):
        
        auth_header = self.get_authenticate_header(self.request)

        if auth_header:
            exc.auth_header = auth_header
        else:
            exc.status_code = status.HTTP_403_FORBIDDEN
	# 点进去看 会发现 get_exception_handler是配置文件中的一个函数 看下面的代码块
    exception_handler = self.get_exception_handler()

    context = self.get_exception_handler_context()
    # 从这里可以看出上面的exception_handler是一个内存地址
    response = exception_handler(exc, context)
	
    # 如果response是None就抛异常 反之正常返回
    if response is None:
        self.raise_uncaught_exception(exc)

    response.exception = True
    return response
def exception_handler(exc, context):
    if isinstance(exc, Http404):
        exc = exceptions.NotFound()
    elif isinstance(exc, PermissionDenied):
        exc = exceptions.PermissionDenied()
	
    # 这一步就是判断 当前的异常是不是属于drf内置的类的对象
    # 如果是 则返回前端可以渲染的 Response
    # 如果不是 则返回None 前端就会爆出错误信息
    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)

    return None

标签:exception,exc,handler,self,request,response,源码,全局,捕获
From: https://www.cnblogs.com/Hqqqq/p/18149601

相关文章

  • Django之settings源码分析
    引入查看源码的前提刚开始阅读一些库的源码的时候,最好选一些代码量少的先感受一下看到看不懂的,没有必要去死磕,挑一些看得懂的,再结合网上的一些文献一.django的两个配置文件一个是暴露给用户可以自己自定义的配置文件也就是项目根目录下的settings.py一个是项目默认的配......
  • 计算机毕业设计源码-基于 SpringBoot 开发的班级综合测评系统研究与实现
    技术栈开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9浏览器:谷歌浏览器3.需求分析用户需求分析根据账号登陆进入班级综合测评管理系统,系统根据角色展示相应......
  • 从源码入手详解ReentrantLock,一个比synchronized更强大的可重入锁
    写在开头随手一翻,发现对于Java中并发多线程的学习已经发布了十几篇博客了,多线程是Java基础中的重中之重!因此,可能还需要十几篇博客才能大致的讲完这部分的知识点,初学者对于这部分内容一定要多花心思,不可马虎!今天我们继续来学习一个重要知识点:ReentrantLockReentrantLock:是一种......
  • proxifier+v2代理软件实现真全局代理(防溯源)
    v2的使用这里就不详细说了打开v2,右下角可以看到端口开启v2代理后,打开proxifer先打开左上角的代理服务器按照以下配置,端口改成v2上面看到的socks5端口也可以左下角检查以下代理有没有问题,有时候可能是代理服务器卡了或者死了接着来到代理规则,按照以下配置......
  • 【记一个小坑】linux源码在window10使用过程中的坑
    在window10解压linux.tar.gz的时候遇到了一下几个问题:(我用的解压软件是Bandzip)1、解压的时候会有如下图的提示,网上有一些人说不用管,直接覆盖,但是并不是所有人都适用,如果你是想要修改linux源码,然后编译安装的话,直接覆盖,之后会造成编译的时候报错:找不到XXX文件原因是windows默......
  • 某游戏忍者全局过异常分析
    虽然这篇文章可能会涉及到某些人的利益,但我还是写了首先,我们先将手机与ce进行桥接(具体的教程b站有)然后我们先找到a内存的过异常(原理就是将当前怪物包改0,当前市面上广为流传的过异常都是这个原理)我们在ce中添加他的地址查看访问他的操作码(触发他)然后我们看到访问了他的......
  • PostgreSQL源码编译安装指南
    一、版本说明centos7.9postgresql12.2二、配置系统基本环境#1.创建postgres用户groupaddpostgresuseradd-gpostgrespostgresecho"666666"|passwdpostgres--stdin#2.配置用户环境变量su-postgrescat>>~/.bash_profile<<EOFexportPGPORT=1922expor......
  • 短视频源码,高效异常处理让您的代码更完美
    在编写Python代码的过程中,我们常常会遇到各种错误和异常。学会有效地处理这些异常,可以让短视频源码更加健壮、稳定。本文将带您深入了解Python异常处理的艺术,让您的短视频源码更加完美!一.异常简介异常是在短视频源码执行过程中发生的事件,通常表示代码中存在错误或异常情况......
  • 企业微信hook 最新版 、企微输入验证码,二次扫码方案、发名片收消息功能,企业微信hook源
    ​产品说明在PC端企业微信客户端上发送自定义名片、封装企业微信功能为DLL,可与其他语言调用实现功能。DLL可以监听企业微信的所有消息接收和群消息,根据需求实现机器人、群发、自动消息推送、聊天机器人、监管数据收集等功能企业微信hook,企业微信功能api,自定义开发功能清......
  • 马扎克,海德汉,哈斯,兄弟,发那科,三菱,西门子,华中数控,knd,广数,宝元,发格,无授权源码采集。机床
    机床联网cnc采集设备联网车间数字化生产追踪 无需授权可跨平台运行任何平台Linuxwindows等 可+:cnccaiji机床数据采集MDC,DNC,可定制开发,有采集驱动支持多品牌cnc系统多设备采集支持转发mqtt推送HTTP马扎克机床数据采集海德汉机床数据采集哈斯机床数据采集......