flask异常处理:abort、errorhandler、app_errorhandler,封装全局异常处理
1. abort()
abort()函数也叫视图终止函数,用于提前退出一个请求,并用指定的错误码返回。既然是视图终止函数,就是说abort()函数是写在视图中的。那么这个函数就不能处理由于url不合法引起的异常,因为一旦url不合法,是无法进入到视图函数中的。
flask-restful中的 abort() 的代码是封装的 flask 的 abort() 代码。
flask abort() 源码:
def abort(status, *args, **kwargs):
    return _aborter(status, *args, **kwargs)
flask-restful 的 abort() 源码:
def abort(http_status_code, **kwargs):
    try:
        original_flask_abort(http_status_code)
    except HTTPException as e:
        if len(kwargs):
            e.data = kwargs
        raise
这里的 original_flask_abort() 即 flask 的 abort()。其实我们也可以自己来封装abort()这个函数,来实现我们需要的功能。
1.1 使用方式一:传递一个错误码
from flask import abort
@app.route("/")
def index():
    # abort函数可以提前终止视图函数
    abort(404)
    # 下面这条消息无法打印出来,因为上面abort函数已经终止了这个视图函数的运行。
    print("我还在运行ing")
    return "Index Page"
参数http_status_code:传递状态码(错误码),必须是标准的http状态码。
直接返回给前端页面一个对应错误码的错误信息。
查看错误码:
from werkzeug.exceptions import default_exceptions
import pprint
pprint.pprint(default_exceptions)
结果:
如果是以下列表之外的,会报服务器内部错误:{"message": "Internal Server Error"}
可以看到2xx与3xx并不在此之列。
{400: <class 'werkzeug.exceptions.BadRequest'>,
 401: <class 'werkzeug.exceptions.Unauthorized'>,
 403: <class 'werkzeug.exceptions.Forbidden'>,
 404: <class 'werkzeug.exceptions.NotFound'>,
 405: <class 'werkzeug.exceptions.MethodNotAllowed'>,
 406: <class 'werkzeug.exceptions.NotAcceptable'>,
 408: <class 'werkzeug.exceptions.RequestTimeout'>,
 409: <class 'werkzeug.exceptions.Conflict'>,
 410: <class 'werkzeug.exceptions.Gone'>,
 411: <class 'werkzeug.exceptions.LengthRequired'>,
 412: <class 'werkzeug.exceptions.PreconditionFailed'>,
 413: <class 'werkzeug.exceptions.RequestEntityTooLarge'>,
 414: <class 'werkzeug.exceptions.RequestURITooLarge'>,
 415: <class 'werkzeug.exceptions.UnsupportedMediaType'>,
 416: <class 'werkzeug.exceptions.RequestedRangeNotSatisfiable'>,
 417: <class 'werkzeug.exceptions.ExpectationFailed'>,
 418: <class 'werkzeug.exceptions.ImATeapot'>,
 422: <class 'werkzeug.exceptions.UnprocessableEntity'>,
 423: <class 'werkzeug.exceptions.Locked'>,
 428: <class 'werkzeug.exceptions.PreconditionRequired'>,
 429: <class 'werkzeug.exceptions.TooManyRequests'>,
 431: <class 'werkzeug.exceptions.RequestHeaderFieldsTooLarge'>,
 451: <class 'werkzeug.exceptions.UnavailableForLegalReasons'>,
 500: <class 'werkzeug.exceptions.InternalServerError'>,
 501: <class 'werkzeug.exceptions.NotImplemented'>,
 502: <class 'werkzeug.exceptions.BadGateway'>,
 503: <class 'werkzeug.exceptions.ServiceUnavailable'>,
 504: <class 'werkzeug.exceptions.GatewayTimeout'>,
 505: <class 'werkzeug.exceptions.HTTPVersionNotSupported'>}
1.2 使用方式二:传递一个json格式字符串
from flask import abort, jsonify
@app.route("/")
def index():
    code = 50000
    data = [{"data1": "lalallala", {"data2": "lolololo"}]
    json_data = jsonify({"code": code, "data": data})
    abort(json_data)
    # 下面这条消息无法打印出来,因为上面abort函数已经终止了这个视图函数的运行。
    print("我还在运行ing")
    return "Index Page"
这种方法相当于 return ,直接把传入abort中的数据返回到前端。
1.3 使用方式三:传递一个响应体
from flask import abort, Response
@app.route("/")
def index():
    res = Response("Not Found", 404, {"name": "ttytty"})  # Response也可以返回响应体信息
    abort(res)
    # 下面这条消息无法打印出来,因为上面abort函数已经终止了这个视图函数的运行。
    print("我还在运行ing")
    return "Index Page"
直接返回给前端这个响应体。方式二和方式三很相似。
2. errorhandler
捕捉当前app或蓝图的状态码,然后可以进行自定义处理。
2.1 简单使用:
from flask import jsonify
from . import admin
@admin.errorhandler(404)
def error_404(error):
    """这个handler可以catch住所有abort(404)以及找不到对应router的处理请求"""
    response = dict(status=0, message="404 Not Found")
    return jsonify(response), 404
@admin.errorhandler(Exception)
def error_500(error):
    """这个handler可以catch住所有的abort(500)和raise exeception."""
    response = dict(status=0, message="500 Error")
    return jsonify(response), 400
class MyError(Exception):
    """自定义错误类"""
    pass
@admin.errorhandler(MyError)
def MyErrorHandle(error):
    response = dict(status=0, message="400 Error")
    return jsonify(response), 400
2.2 封装成全局异常捕获处理:
- 自定义异常类(有需要的话)
 
from werkzeug.exceptions import HTTPException
class EigenException(HTTPException):
    code = 500
    eigen_code = 4000
    description = 'Inner Server Error'
class RequestError(EigenException):
    code = 400
class DataNotFound(RequestError):
    code = 404
    eigen_code = 4004
    description = 'Data Not Found'
    def __init__(self, message):
        self.description = '%s Not Found' % message
class InvalidRequest(RequestError):
    eigen_code = 4005
    description = 'Invalid Request URL'
class MissingKey(RequestError):
    eigen_code = 4006
    description = 'Missing Key'
    def __init__(self, key):
        self.description = 'Missing Key `%s`' % key
- 捕获异常并处理:
 
# 制定一个响应
def json_response(code, error, status_code):
    response = make_response(json.dumps(dict(code=code, error=error)), status_code)
    response.headers['Content-Type'] = 'application/json; charset=utf-8'
    return response
# 异常捕获处理
@app.errorhandler(Exception)
def handler_exception(e):
    if isinstance(e, 其他异常):
        code, status_code, error = 4000, 400, e.description
    elif isinstance(e, EigenException):
        code, status_code, error = e.eigen_code, e.code, e.description
    elif isinstance(e, HTTPException):
        code, status_code, error = e.code, e.code, e.description
    else:
        code, status_code, error = 5000, 500, '%s(%s)' % (e.__class__.__name__, str(e))
    return json_response(code, error, status_code)
3. app_errorhandler
捕捉全局状态码,并进行自定制异常处理
在蓝本中编写错误处理程序有点不同,如果使用errorhandler修饰器,那么只有蓝本中的错误才会触发。如果想注册全局的错误处理程序,要用app_errorhandler。
例如:
from bookapp import bokkapp
@bookapp.app_errorhandler(Exception)
def handler_exception(e):
    if isinstance(e, 其他异常):
        code, status_code, error = 4000, 400, e.description
    elif isinstance(e, EigenException):
        code, status_code, error = e.eigen_code, e.code, e.description
    elif isinstance(e, HTTPException):
        code, status_code, error = e.code, e.code, e.description
    else:
        code, status_code, error = 5000, 500, '%s(%s)' % (e.__class__.__name__, str(e))
    response = dict(code=code, status=status_code, msg=error)
    return jsonify(response)
**注意: **当我们不是使用的工厂模式创建app时,app.errorhandler(401),即可捕捉全局401状态;若使用了create_app方式创建app,则无法进行捕捉,若想捕捉,可以在蓝图中写,如admin.errorhandler(401),即捕捉admin蓝图下所有401状态码,admin.app_errorhandler(401),则是捕捉的全局的401状态码,即其他蓝图中的401状态,也会被捕捉,进行处理
参考文章:
flask异常处理:abort、errorhandler、app_errorhandler,封装全局异常处理的更多相关文章
- WCF全局异常处理
		
在用wcf做为单纯的服务端的时候,发生错误是常有的事情,特别是在调用其他系统提供的接口的时候,发生的一些错误总是让人摸不着头脑,严重影响了错误的定位.做.net web开发的时候,我们可以在Globa ...
 - Spring Boot 2.x 系列教程:WebFlux REST API 全局异常处理 Error Handling
		
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 本文内容 为什么要全局异常处理? WebFlux REST 全 ...
 - 【Flask】abort和errorhandler、app_errorhandler进行请求中断及自定义异常处理
		
在view函数中,如果需要中断request,可以使用abort(500)或者直接raise exception.当然我们还需要返回一个出错信息给前端,所以需要定制一下ErrorHandler.一般只 ...
 - SpringBoot整合全局异常处理&SpringBoot整合定时任务Task&SpringBoot整合异步任务
		
============整合全局异常=========== 1.整合web访问的全局异常 如果不做全局异常处理直接访问如果报错,页面会报错500错误,对于界面的显示非常不友好,因此需要做处理. 全局异 ...
 - NET MVC全局异常处理(一)  【转载】网站遭遇DDoS攻击怎么办  使用 HttpRequester 更方便的发起 HTTP 请求  C#文件流。  Url的Base64编码以及解码   C#计算字符串长度,汉字算两个字符  2019周笔记(2.18-2.23)  Mysql语句中当前时间不能直接使用C#中的Date.Now传输  Mysql中Count函数的正确使用
		
NET MVC全局异常处理(一) 目录 .NET MVC全局异常处理 IIS配置 静态错误页配置 .NET错误页配置 程序设置 全局异常配置 .NET MVC全局异常处理 一直知道有.NET有相关 ...
 - 014-Spring Boot web【三】拦截器HandlerInterceptor、异常处理页面,全局异常处理ControllerAdvice
		
一.拦截器HandlerInterceptor 1.1.HandlerInterceptor接口说明 preHandle,congtroller执行前,如果返回false请求终端 postHandle ...
 - 第6章 AOP与全局异常处理6.5-6.11 慕课网微信小程序开发学习笔记
		
https://coding.imooc.com/learn/list/97.html 目录: 第6章 AOP与全局异常处理6-1 正确理解异常处理流程 13:236-2 固有的处理异常的思维模式与流 ...
 - WPF MVVM UI分离之《交互与数据分离》  基础才是重中之重~delegate里的Invoke和BeginInvoke  将不确定变为确定系列~目录(“机器最能证明一切”)  爱上MVC3系列~全局异常处理与异常日志  基础才是重中之重~lock和monitor的区别  将不确定变成确定~我想监视我的对象,如果是某个值,就叫另一些方法自动运行  将不确定变成确定~LINQ DBML模型可以对
		
WPF MVVM UI分离之<交互与数据分离> 在我们使用WPF过程中,不可避免并且超级喜欢使用MVVM框架. 那么,使用MVVM的出发点是视觉与业务逻辑分离,即UI与数据分离 诸如下 ...
 - Spring中通过java的@Valid注解和@ControllerAdvice实现全局异常处理。
		
通过java原生的@Valid注解和spring的@ControllerAdvice和@ExceptionHandler实现全局异常处理的方法: controller中加入@Valid注解: @Req ...
 
随机推荐
- C# Net 去除图片白边
			
代码根据别人的进行改写,效果更好 直接拷贝使用 名称空间: using System.Drawing; 代码: /// <summary> /// 裁剪图片(去掉百边) /// </ ...
 - eclipse 搭建springboot项目pom.xml报错
			
1. 报错信息 2. 解决方法 在pom.xml文件中加入maven版本修改 <maven-jar-plugin.version>3.1.1</maven-jar-plugin.ve ...
 - XGBoost使用教程(与sklearn一起使用)二
			
一.导入必要的工具包# 运行 xgboost安装包中的示例程序from xgboost import XGBClassifier # 加载LibSVM格式数据模块from sklearn.datase ...
 - windows平台上MongoDB安装配置
			
我按照原文方法操作,无法连接mongod服务,可能哪里出了问题. 以下是小页的教程:https://www.cnblogs.com/littlepage/p/10992336.html 视频参考: ...
 - ubuntu无法连接网络
			
一,先说一下VMware软件和linux镜像的版本: VMware Workstation 14 Pro ubuntu-14.04.6-desktop-amd64.iso 二,遇到的问题 在第一次安装 ...
 - 201871010121-王方《面向对象程序设计(Java)》第四周学习总结
			
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
 - Consul 学习资料
			
资料 网址 Consul 入门指南 https://book-consul-guide.vnzmi.com/
 - pyinstaller安装及使用
			
pyinstaller使用 将.py文件转换成无需源码的.exe可执行文件 下载 1.打开cmd直接输入pip install pyinstaller即可下载 2.如第一种方法无法下载,打开pyins ...
 - 排序算法-冒泡排序(Java)
			
package com.rao.sort; import java.util.Arrays; /** * @author Srao * @className BubbleSort * @date 20 ...
 - Scrapy笔记09- 部署
			
Scrapy笔记09- 部署 本篇主要介绍两种部署爬虫的方案.如果仅仅在开发调试的时候在本地部署跑起来是很容易的,不过要是生产环境,爬虫任务量大,并且持续时间长,那么还是建议使用专业的部署方法.主要是 ...