异常模块源码入口

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. hdu4403暴力搜索

    题意:      给你一个数字串,让你在里面添加一个=和若干个+,使等式成立. 思路:      lmax最大是15,直接暴搜,无压力,关键是判重,要在答案的时候判重,一开始在进队列之前判的,各种wa ...

  2. hdu4279 找规律+小想法

    题意:      蛋疼的题意,最后是泽神给我讲的题意,题意是对于一个数来说,如果他不能整除另一个数同时他和另一个数非互质,那么另一个数就是这个数的特别数,如10 的特别数有 4 6 8三个,同时题目还 ...

  3. 反病毒攻防研究第004篇:利用WinRAR与AutoRun.inf实现自启动

    一.前言 由之前的一系列研究可以发现,为了使得"病毒"能够实现自启动,我也是煞费苦心,采取了各种方式,往往需要编写冗长的代码并且还需要掌握系统底层或注册表的很多知识才可以.而这次我 ...

  4. POJ1698 最大流或者匈牙利

    题意:       一个人他有n个任务,每个任务都有一些限制:  (1)只能在一个星期中指定的日子去做,比如周1 2 6啥的  (2)总工作量有几天,就是一共要工作几天  (3)必须在几周之内完成,就 ...

  5. 还在一个模块打天下嘛?你知道引入Jetpack架构后,你的App会发生哪些奇妙的变化吗?

    前言 上篇文章我给大家分享了我对Android架构的理解,从思想层面去讲述架构的演进过程.很多小伙伴读完后拍手叫好,表示还想听我讲一下对Jetpack 架构的看法,本着帮人帮到底的精神,今天我将再次动 ...

  6. 使用jenkins一键打包发布vue项目

    jenkins的安装 Jenkins是一款开源 CI&CD 软件,用于自动化各种任务,包括构建.测试和部署软件. Jenkins 支持各种运行方式,可通过系统包.Docker 或者通过一个独立 ...

  7. Educational Codeforces Round 101 (Rated for Div. 2)

    A. Regular Bracket Sequence 题意:题目中给(和)还有?,其中?可以转换成为()中的任何一个,并且所给样例中只出现一次(),问能不能括号匹配 思路:直接看第一个和最后一个能不 ...

  8. Codeforces Round #660 (Div. 2)

    A. Captain Flint and Crew Recruitment 题意:定义了一种数(接近质数),这种数可以写成p*q并且p和q都是素数,问n是否可以写成四个不同的数的和,并且保证至少三个数 ...

  9. FreeSWITCH的安装与使用

    FreeSWITCH

  10. 日常Bug排查-系统失去响应-Redis使用不当

    日常Bug排查-系统失去响应-Redis使用不当 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_. Bug现场 开发反应线上系统出现失去响 ...