Django(50)drf异常模块源码分析
异常模块源码入口
APIView类中dispatch方法中的:response = self.handle_exception(exc)
源码分析
我们点击handle_exception跳转,查看该方法源码
def handle_exception(self, exc):
    """
    Handle any exception that occurs, by returning an appropriate response,
    or re-raising the error.
    """
    # 判断异常类型是否是没有认证的类型,最后返回403状态码
    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(),我们可以点击查看该方法源码
def get_exception_handler(self):
    """
    Returns the exception handler that this view uses.
    """
    return self.settings.EXCEPTION_HANDLER
该方法返回该视图的异常处理方法,从返回的内容,我们可以知道,该方法在settings文件中有个默认值,进入settings可查看到
'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
异常处理的默认方法就是views下的exception_handler方法,我们再进入查看该方法源码
def exception_handler(exc, context):
    """
    Returns the response that should be used for any given exception.
    By default we handle the REST framework `APIException`, and also
    Django's built-in `Http404` and `PermissionDenied` exceptions.
    Any unhandled exceptions may return `None`, which will cause a 500 error
    to be raised.
    """
    # 判断异常是否是404
    if isinstance(exc, Http404):
        exc = exceptions.NotFound()
    # 判断异常是否是没有权限
    elif isinstance(exc, PermissionDenied):
        exc = exceptions.PermissionDenied()
    # 判断异常是否是drf的基类异常,该异常提供了状态码和异常字段detail
    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
        # 判断detail是否是list类型或dict类型
        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
从上述代码我们可以知道,当response返回为None时,是不会返回异常信息,而是直接抛出异常,所以我们可以自定义异常类
自定义异常
在我们的app目录下,创建utils包,并创建exceptions文件,并写入如下源码:
from rest_framework.response import Response
from rest_framework.views import exception_handler as drf_exception_handler
def exception_handler(exc, context):
    response = drf_exception_handler(exc, context)
    if response is None:
        print(f"{context['view']} - {context['request'].method} - {exc}")
        return Response(status=500, data="服务器错误")
    return response
最后我们将默认异常信息配置改为自己的配置即可,在settings文件中写入如下配置
REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'drf_app.utils.exceptions.exception_handler',
}
以后碰到response响应为None的时候,我们就会抛出服务器错误的异常信息
总结
为什么要自定义异常模块?
- 所有经过
drf的APIView视图类产生的异常,都可以提供异常处理方案 drf默认提供了异常处理方案(rest_framework.views.exception_handler),但是处理范围有限drf提供的处理方案两种,处理了返回异常现象,没处理返回None(后续就是服务器抛异常给前台)- 自定义异常的目的就是解决
drf没有处理的异常,让前台得到合理的异常信息返回,后台记录异常具体信息 
Django(50)drf异常模块源码分析的更多相关文章
- Django(51)drf渲染模块源码分析
		
前言 渲染模块的原理和解析模块是一样,drf默认的渲染有2种方式,一种是json格式,另一种是模板方式. 渲染模块源码入口 入口:APIView类中dispatch方法中的:self.response ...
 - Django(48)drf请求模块源码分析
		
前言 APIView中的dispatch是整个请求生命过程的核心方法,包含了请求模块,权限验证,异常模块和响应模块,我们先来介绍请求模块 请求模块:request对象 源码入口 APIView类中di ...
 - Django(49)drf解析模块源码分析
		
前言 上一篇分析了请求模块的源码,如下: def initialize_request(self, request, *args, **kwargs): """ Retu ...
 - DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render
		
DRF框架 全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...
 - Django的settings文件部分源码分析
		
Django的settings文件部分源码分析 在编写Django项目的过程中, 其中一个非常强大的功能就是我们可以在settings文件配置许多选项来完成我们预期的功能, 并且这些配置还必须大写, ...
 - nginx健康检查模块源码分析
		
nginx健康检查模块 本文所说的nginx健康检查模块是指nginx_upstream_check_module模块.nginx_upstream_check_module模块是Taobao定制的用 ...
 - Spark Scheduler模块源码分析之TaskScheduler和SchedulerBackend
		
本文是Scheduler模块源码分析的第二篇,第一篇Spark Scheduler模块源码分析之DAGScheduler主要分析了DAGScheduler.本文接下来结合Spark-1.6.0的源码继 ...
 - Spark Scheduler模块源码分析之DAGScheduler
		
本文主要结合Spark-1.6.0的源码,对Spark中任务调度模块的执行过程进行分析.Spark Application在遇到Action操作时才会真正的提交任务并进行计算.这时Spark会根据Ac ...
 - Zepto事件模块源码分析
		
Zepto事件模块源码分析 一.保存事件数据的handlers 我们知道js原生api中要移除事件,需要传入绑定时的回调函数.而Zepto则可以不传入回调函数,直接移除对应类型的所有事件.原因就在于Z ...
 
随机推荐
- PHP laravel系列之Blade模版
			
一.什么是Blade模版? Blade 是 Laravel 提供的一个既简单又强大的模板引擎. 和其他流行的 PHP 模板引擎不一样,Blade 并不限制你在视图中使用原生 PHP 代码.所有 Bla ...
 - hdu4291 暴力循环节+矩阵快速幂
			
题意: 给你一个关系式,x[n] = 3*x[n-1] + x[n-2],求x(x(x[n]))%1000000007. 思路: 做这个题目要明确一点,就是对于取余操作大多数时 ...
 - Linux系统调用表
			
Linux系统调用表 记录下来,免得到处找 32位 int 0x80 %eax Name Source %ebx %ecx %edx %esx %edi 1 sys_exit kernel/exit. ...
 - Jedis基础详解
			
Jedis 使用Java来操作Redis 什么是Jedis 是Redis官方推荐的Java操作Redis中间件, 如果你要使用Java操作Redis, 那么就该对jedis熟悉 测试 导入对应的依赖 ...
 - dubbo服务暴露原理-远程暴露
			
1.与本地暴露相比,远程暴露也大同小异 我们已经到了第三个关键词Procotol我们来看看他的继承体系图 按照经典图的路线,我们下一个关键词应该就是Server了,从方法名openServer(url ...
 - 05.24  ICPC 2019-2020 North-Western Russia Regional Contest复现赛+Codeforces Round #645 (Div. 2)
			
A.Accurate Movement(复现赛) 题意:两个木块最左边都在0的位置,最右边分别为a,b(b>a),并且短的木条只能在长木条内移动,问两个木条需要移动多少次才能使两个木条的右端都在 ...
 - Java安全之Filter权限绕过
			
Java安全之Filter权限绕过 0x00 前言 在一些需要挖掘一些无条件RCE中,大部分类似于一些系统大部分地方都做了权限控制的,而这时候想要利用权限绕过就显得格外重要.在此来学习一波权限绕过的思 ...
 - RHEL_高级磁盘管理(vdo、stratis)
			
RHEL高级磁盘管理-VDO VDO简介 Virtual Data Optimizer 通过数据去重.压缩的方式来优化存储空间. VDO层放置在现有块存储设备上,例如Raid设备.本地磁盘设备. LV ...
 - Python菜鸟100例
			
题目地址 #-*- codeing = utf-8 -*- #@Time : 2021/3/18 21:17 #@Author : HUGBOY #@File : 1.py #@Software: P ...
 - qt利用QT designer构建第一个界面helloworld工程
			
qt利用QT designer构建第一个界面helloworld工程原创ZJE_ANDY 发布于2017-04-07 20:25:28 阅读数 6613 收藏展开第一步:点击New Project 第 ...