异常模块源码入口

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的时候,我们就会抛出服务器错误的异常信息

总结

为什么要自定义异常模块?

  1. 所有经过drfAPIView视图类产生的异常,都可以提供异常处理方案
  2. drf默认提供了异常处理方案(rest_framework.views.exception_handler),但是处理范围有限
  3. drf提供的处理方案两种,处理了返回异常现象,没处理返回None(后续就是服务器抛异常给前台)
  4. 自定义异常的目的就是解决drf没有处理的异常,让前台得到合理的异常信息返回,后台记录异常具体信息

Django(50)drf异常模块源码分析的更多相关文章

  1. Django(51)drf渲染模块源码分析

    前言 渲染模块的原理和解析模块是一样,drf默认的渲染有2种方式,一种是json格式,另一种是模板方式. 渲染模块源码入口 入口:APIView类中dispatch方法中的:self.response ...

  2. Django(48)drf请求模块源码分析

    前言 APIView中的dispatch是整个请求生命过程的核心方法,包含了请求模块,权限验证,异常模块和响应模块,我们先来介绍请求模块 请求模块:request对象 源码入口 APIView类中di ...

  3. Django(49)drf解析模块源码分析

    前言 上一篇分析了请求模块的源码,如下: def initialize_request(self, request, *args, **kwargs): """ Retu ...

  4. DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render

    DRF框架    全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...

  5. Django的settings文件部分源码分析

    Django的settings文件部分源码分析 在编写Django项目的过程中, 其中一个非常强大的功能就是我们可以在settings文件配置许多选项来完成我们预期的功能, 并且这些配置还必须大写, ...

  6. nginx健康检查模块源码分析

    nginx健康检查模块 本文所说的nginx健康检查模块是指nginx_upstream_check_module模块.nginx_upstream_check_module模块是Taobao定制的用 ...

  7. Spark Scheduler模块源码分析之TaskScheduler和SchedulerBackend

    本文是Scheduler模块源码分析的第二篇,第一篇Spark Scheduler模块源码分析之DAGScheduler主要分析了DAGScheduler.本文接下来结合Spark-1.6.0的源码继 ...

  8. Spark Scheduler模块源码分析之DAGScheduler

    本文主要结合Spark-1.6.0的源码,对Spark中任务调度模块的执行过程进行分析.Spark Application在遇到Action操作时才会真正的提交任务并进行计算.这时Spark会根据Ac ...

  9. Zepto事件模块源码分析

    Zepto事件模块源码分析 一.保存事件数据的handlers 我们知道js原生api中要移除事件,需要传入绑定时的回调函数.而Zepto则可以不传入回调函数,直接移除对应类型的所有事件.原因就在于Z ...

随机推荐

  1. CS与MSF之间的会话传递

    0x01 MSF会话传递到CS 1. CS上的操作 点击Cobalt Strike然后选择监听器,创建一个HTTPS Beacon的监听器即可 创建成功后如下 2. MSF上的操作 前提是已经获取到了 ...

  2. 1028 List Sorting

    Excel can sort records according to any column. Now you are supposed to imitate this function. Input ...

  3. Unity基础-脚本生命周期

    理解Unity脚本的生命周期对游戏开发很重要,这篇文章对生命周期做一个记录和总结.Unity的脚本生命周期(消息),也就是在脚本运行时,自动并且按顺序执行的一系列函数.在unity官网中有对生命周期详 ...

  4. 【新手/零基础】Hexo+Gitee个人博客搭建教程--详细版

    前言 点此转到--精简版 可能很多小伙伴都有搭建一个属于自己的博客的想法.但是经常是无奈于自己匮乏的知识.但是,每个老手都是新手过来的,再困难的事情,只要肯花一点时间都可以办成. 本次教程分为详细版和 ...

  5. 轮子:DateUtil.java

    日期工具类 import java.text.SimpleDateFormat; import java.util.Date; public class DateUtil { public stati ...

  6. php swoole 和 websocket的初次碰撞

    php swoole 扩展仿佛为php开发打开了一扇窗户 阅读文档 https://wiki.swoole.com php workman和swoole原来是两个东东 swoole的使用范围更广,能做 ...

  7. Python小游戏 -- 猜数字

    Python初学者小游戏:猜数字 游戏逻辑:电脑随机生成一个数字,然后玩家猜数字,电脑提示猜的数字大了还是小了,供玩家缩小数字范围,达到既定次数后,玩家失败.若在次数内猜对,玩家获胜. 涉及知识点:r ...

  8. UVA11388GCD LCM

    题意:       输入两个整数G,L,找出两个正整数a,b使得gcd(a ,b)=G,lcm(a ,b)=L,如果有多组解,输出最小的a的那组,如果没解,输出-1. 思路:       比较简单,如 ...

  9. SSH后门万能密码

    当我们在获得一台Linux服务器的 root 权限后,我们第一想做的就是如何维持这个权限,维持权限肯定想到的就是在目标服务器留下一个后门.但是留普通后门,肯定很容易被发现.我们今天要讲的就是留一个SS ...

  10. Win64 驱动内核编程-29.强制解锁文件

    强制解锁文件 强制解锁因其他进程占用而无法删除的文件. 1.调用 ZwQuerySystemInformation 的 16 功能号来枚举系统里的句柄 2.打开拥有此句柄的进程并把此句柄复制到自己的进 ...