首页 > 其他分享 >全局异常处理

全局异常处理

时间:2023-05-11 17:00:10浏览次数:27  
标签:exception exc 处理 self handler 全局 异常 response drf

目录

一、全局异常处理

# APIView的dispatch方法中运行了三大认证,然后运行了视图类的方法,如果出了异常,会被异常捕获,捕获后统一处理
    def dispatch(self, request, *args, **kwargs):
        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
    
    
# drf 内置了一个函数,只要上面过程出了异常,就会执行这个函数,这个函数只处理的drf的异常
	-主动抛的非drf异常
    -程序出错了 
    都不会被处理
    我们的目标,无论主动抛还是程序运行出错,都同意返回规定格式--》能记录日志
    公司里一般返回   {code:999,'msg':'系统错误,请联系系统管理员'}
    
    
    
# 写一个函数,内部处理异常,在配置文件中配置一下即可


'第一步:首先在drf的配置文件中有一个配置信息如下(这个后面再配置,先挑出来讲而已)'
# Exception handling
    'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
    '这个配置就是处理drf内部异常的配置文件,如果我们想要进行自定义,就需要在dango的配置文件中自行注册进行替换'
    
'第二步:我们查看dispatch中的异常捕获,发现handle_exception处理了这些异常捕获的信息,而他的参数就是错误信息'

 response = self.handle_exception(exc)
    
'第三步:我们进入他的源码发现他返回的信息是response,并且这个response是由exception_handler方法获得的'


    def handle_exception(self, exc):
        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()

        context = self.get_exception_handler_context()
        response = exception_handler(exc, context)

        if response is None:
            self.raise_uncaught_exception(exc)

        response.exception = True
        return response

'第四步:我们可以看到他则是来自上面的一行代码'
    
    exception_handler = self.get_exception_handler()
    
'第五步:进入这个get_exception_handler方法的源码,我们可以发现他就是拿了配置文件中的配置返回出去'
    
        def get_exception_handler(self):
        return self.settings.EXCEPTION_HANDLER
    
'而配置信息中对应的是一个函数,因此exception_handler的值就相当于是获取这个函数的结果'
    
    def exception_handler(exc, context):
    if isinstance(exc, Http404):
        exc = exceptions.NotFound()
    elif isinstance(exc, PermissionDenied):
        exc = exceptions.PermissionDenied()

    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
    
    
'研究了源码之后我们就开始自己编写,因为原本的异常处理函数有两个参数,因此我们也需要上两个参数,而它的源码太多了,我们可以跟面向对象的派生方法一样,在我们自行定义的函数内调用原本的函数,在此基础上进行自定义'
    
def common_exception_handler(exc, context):
    # exc 错误对象
    # context:上下文,有view:当前出错的视图类的对象,args和kwargs视图类方法分组出来的参数,request:当次请求的request对象
    # 只要走到这里,就要记录日志 ,只有错了,才会执行这个函数
    # 记录日志尽量详细
    print('时间,登录用户id,用户ip,请求方式,请求地址,执行的视图类,错误原因')
    res = exception_handler(exc, context)
    if res:  # 通过观察原来的函数我们发现有值的时候,说明返回了Response 对象,没有值说明返回None
        # 如果是Response 对象说明是drf的异常,已经被处理了,如果是None表明没有处理,就是非drf的异常
        res = Response(data={'code': 888, 'msg': res.data.get('detail', '请联系系统管理员')}) # 这里就是自定义返回的信息的格式,处理的就是原本的drf中的报错
    else:
        # res = Response(data={'code': 999, 'msg': str(exc)})
        # 记录日志
        res = Response(data={'code': 999, 'msg': '系统错误,请联系系统管理员'})
        # 这里就是处理非drf报错的代码,如果想看具体报错可以把msg的值换成参数中的exc接收的错误信息


    return res


# 在配置文件中配置
REST_FRAMEWORK = {
	'EXCEPTION_HANDLER': 'app01.exceptions.common_exception_handler',
}


标签:exception,exc,处理,self,handler,全局,异常,response,drf
From: https://www.cnblogs.com/zhihuanzzh/p/17391609.html

相关文章

  • 【Java】Java 异常处理
    1、什么是异常?将程序执行中发生的不正常情况称为“异常”2、Java程序在执行过程中所发生的异常事件可分为两类java.lang.Error:一般不编写针对性的代码进行处理java.lang.Exception:可以进行异常的处理Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等......
  • k8s证书续签及异常:You must be logged in to the server
    1、证书续签(k8smaster节点执行):  #备份kubernetes配置sudocp-r/etc/kubernetes/etc/kubernetes_bak#更新证书sudokubeadmcertsrenewall#查看证书过期时间sudokubeadmcertscheck-expiration#删除conf文件sudorm-rf/etc/kubernetes/*.conf#重新生......
  • Pytorch数据预处理
    为了能用深度学习来解决现实世界的问题,我们经常从预处理原始数据开始,而不是从那些准备好的张量格式数据开始。首先我们准备一个人工数据集: 这是一个.csv格式(用逗号隔开)的数据文件。该数据集有四行三列。其中每行描述了房间数量(“NumRooms”)、巷子类型(“Alley”)和房屋价格(“P......
  • SpringBoot中@ControllerAdvice/@RestControlAdvice+@ExceptionHandler实现全局异常捕
    场景在编写Controller接口时,为避免接口因为未知的异常导致返回不友好的结果和提示。如果不进行全局异常捕获则需要对每个接口进行try-catch或其他操作。 可以对Controller进行全局的异常捕获和处理,一旦发生异常,则返回通用的500响应码与通用错误提示。并将异常发生的具体的......
  • LSTM算法做时间序列的预测,使用matlab自带的LSTM工具箱函数,预测精度很高,网络参数最优化
    LSTM算法做时间序列的预测,使用matlab自带的LSTM工具箱函数,预测精度很高,网络参数最优化处理,误差评价指标计算。ID:6768660696244807......
  • ps批量处理图片分辨率 rename批量修改名称
    制作linux项目,需要批量处理部分图片分辨率录制动作注意此处存储,经过测试直接存储会导致失败,此处选择的是另存方式 文件->存储为(A)...   此处另存选择的是png格式  执行动作  文件修改完毕,有时候需要统一名称,可以自己写bat脚本,但是学习成本有点高,此......
  • EDI系统如何设置延迟处理数据?
    在EDI系统中,延迟处理数据是一种非常重要的功能,可以使数据处理更加灵活,从而提高整个系统的效率。由于EDI系统进行数据交换的速度非常快。当数据被发送到接收方时,接收方需要立即对其进行处理。然而,在某些情况下,接收方可能无法立即处理数据,例如在系统维护期间或者其他原因。需要将数......
  • 移动端滑动验证时页面跟随移动的问题处理
    在写一个移动端网页的滑动验证时,如果手指在屏幕上滑动会触发手机自带的事件。比如手机切屏或返回上一页等等。有两种网页端的方法可以阻止移动端左右滑动触发上一下和下一页的操作。1.CSS方法:html{touch-action:none;touch-action:pan-y;}2.使用JS代码:varsta......
  • 图像分割例如可以对脑部CT的图像进行处理,把大脑白质部分分割出来。
    图像分割例如可以对脑部CT的图像进行处理,把大脑白质部分分割出来。或者是视网膜的血管提取。ID:8150613310466813......
  • BLDC无刷直流电机双闭环控制 1.使用霍尔传感器进行换相处理
    BLDC无刷直流电机双闭环控制1.使用霍尔传感器进行换相处理,转速环和电流环采用PI控制。2.提供参考文献和仿真模型;ID:6320676803026473......