【python】flask请求钩子,主动抛出异常与异常捕获

在这里插入图片描述

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN新星创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,前后端开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,linux,shell脚本等实操经验,网站搭建,面试宝典等分享。

所属的专栏:flask框架零基础,进阶应用实战教学
景天的主页:景天科技苑

文章目录

  • 请求全局钩子[hook]
  • flask异常抛出和捕获异常
    • 主动抛出HTTP异常
    • 捕获异常
    • 案例分析

请求全局钩子[hook]

此处的全局钩子,其实就是类似django里面的中间件。 也就是只要调用或者注册了,在http请求响应中是必然执行的。

在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如:

  • 在项目运行开始时,建立数据库连接,或创建连接池;
  • 在客户端请求开始时,根据需求进行身份识别,权限校验;
  • 在请求结束视图返回数据时,指定转换数据的格式,或者记录操作日志;

为了让每个视图函数避免编写重复功能的代码,Flask提供了通用设置的功能,即请求钩子。

请求钩子是通过装饰器的形式实现,Flask支持如下四种请求钩子(注意:钩子的装饰器名字是固定):

  • before_first_request:

    • 在处理第一个请求前执行[项目刚运行第一次被客户端请求时执行的钩子]
    • 在flask2.2.4 版本之后,不再有这个钩子,目前没找到更好的替代方案
  • before_request:

    • 在每一次请求前执行[项目运行后,每一次接收到客户端的request请求都会执行一次]
    • 如果在某修饰的函数中返回了一个响应,视图函数将不再被调用
  • after_request

    • 如果没有抛出错误,在每次请求后执行
    • 接受一个参数:视图函数作出的响应
    • 在此函数中可以对响应值在返回之前做最后一步修改处理
    • 需要将参数中的响应在此参数中进行返回
  • teardown_request:

    • 在每一次请求后执行
    • 接受一个参数:错误信息,如果有相关错误抛出,就可以拿到错误
    • 需要设置flask的配置DEBUG=False,teardown_request才会接受到异常对象。
    • flask3.0之后,flask=True也能接收到报错信息了

代码:

from flask import Flask, session

# 应用实例对象
app = Flask(__name__)

"""给app单独设置配置项"""
# 设置秘钥
app.config["SECRET_KEY"] = "my SECRET KEY"


# @app.before_first_request
# def before_first_request():
#     """
#     这个钩子会在项目启动后第一次被用户访问时执行
#     可以编写一些初始化项目的代码,例如,数据库初始化,加载一些可以延后引入的全局配置
#     """
#     print("----before_first_request----")
#     print("系统初始化的时候,执行这个钩子方法")
#     print("会在接收到第一个客户端请求时,执行这里的代码")



@app.before_request
def before_request():
    """
    这个钩子会在每次客户端访问视图的时候执行
    # 可以在请求之前进行用户的身份识别,以及对于本次访问的用户权限等进行判断。..
    """
    print("----before_request----")
    print("每一次接收到客户端请求时,执行这个钩子方法")
    print("一般可以用来判断权限,或者转换路由参数或者预处理客户端请求的数据")


@app.after_request
def after_request(response):   #注意,这个需要有个参数,用来接收响应
    print("----after_request----")
    print("在处理请求以后,执行这个钩子方法")
    print("一般可以用于记录会员/管理员的操作历史,浏览历史,清理收尾的工作")

    response.headers["Content-Type"] = "application/json"
    response.headers["Company"] = "python.Edu..."

    # 必须返回response参数
    return response


@app.teardown_request
def teardown_request(exc):
    print("----teardown_request----")
    print("在每一次请求以后,执行这个钩子方法")
    print("如果有异常错误,则会传递错误异常对象到当前方法的参数中")
    # 在项目关闭了DEBUG模式以后,则异常信息就会被传递到exc中,我们可以记录异常信息到日志文件中
    print(f"错误提示:{exc}")  # 异常提示


@app.route("/")
def index():
    print("-----------视图函数执行了---------------")
    return "ok"




if __name__ == '__main__':
    # 启动项目的web应用程序
    app.run(host="0.0.0.0", port=5000, debug=True)

浏览器访问,看到响应头被修改
在这里插入图片描述

看下终端打印
先执行before_request,再执行after_request,最后执行teardown_request
在这里插入图片描述

我们人为设置个错误,然后让teardown_request接收
当debug=True时,能接收到错误信息
在这里插入图片描述

但是页面会报错
在这里插入图片描述

当debug=False时,也能接收到错误信息
在这里插入图片描述

页面显示500
在这里插入图片描述

flask异常抛出和捕获异常

主动抛出HTTP异常

  • abort 方法
    • 抛出一个给定状态代码的 HTTPException 或者 指定响应,例如想要用一个页面未找到异常来终止请求,你可以调用 abort(404)
  • 参数:
    • code – HTTP的错误状态码

使用案例:

from flask import Flask,abort,request
app = Flask(import_name=__name__)


# 配置类
class Config(object):
    DEBUG = True     # 开启调试模式

# 加载配置
app.config.from_object(Config)


@app.route("/")
def index():
    # try:
    #     1/0
    # except:
    #     abort(500)

    #当请求查询参数中不包含username时,就报错
    username = request.args.get("username")
    if username is None:
        abort(400)

    return "ok"

if __name__ == '__main__':
    app.run()

我们先不带查询参数username访问,直接报400错误代码
在这里插入图片描述

但是:
abort,只能抛出 HTTP 协议的错误状态码,一般用于权限等页面上错误的展示提示.

abort 在有些前后端分离的项目里面不会被使用,往往在业务错误的时候使用raise进行抛出错误类型,而不是抛出http异常。

捕获异常

  • app.errorhandler 装饰器
    • 注册一个错误处理程序,当程序抛出指定错误状态码的时候,就会调用该装饰器所装饰的方法
  • 参数:
    • code_or_exception – HTTP的错误状态码或指定异常
  • 例如统一处理状态码为500的错误给用户友好的提示

案例:

from flask import Flask, request, abort


app = Flask(__name__)

#自定义一个异常类
class NetWorkError(Exception):
    pass

@app.route("/")
def index():
    password = request.args.get("password")
    if password != "123456":
        # 主动抛出HTTP异常!
        # abort的第一个参数:表示本次抛出的HTTP异常状态码,后续其他参数,表示错误相关的提示内容。
        # abort(400, "密码错误!")
        raise NetWorkError("网络请求出错!")
        # print(hello)
    return "ok"


# @app.errorhandler的参数是异常类型或者HTTP状态码
@app.errorhandler(NameError)
def NameErrorFunc(exc):
    """
    针对变量命名的异常处理
    :param exc:
    :return:
    """
    print(exc.__traceback__)
    return {"error": f"{exc}"}


@app.errorhandler(400)
def error_400(exc, *args, **kwargs):
    print(exc.__traceback__)
    print(exc.code)        # 上面abort传递的错误状态码
    print(exc.description) # 上面abort传递的错误描述
    return {"error": f"{exc.description}"}


@app.errorhandler(404)
def error_404(exc):
    print(exc.code)        # 上面abort传递的错误状态码
    print(exc.description) # 上面abort传递的错误描述
    return {"error": "当前页面不存在!"}

@app.errorhandler(NetWorkError)
def network_error(exc):
    return {"error": f"{exc}"}

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000, debug=True)

案例分析

1.当我们请求中查询参数不包含password或者password的值不是123456时,我们abort(400, “密码错误”) 抛出密码错误,和400错误状态码
在这里插入图片描述

我们通过errorhandler来捕获这个错误状态码,然后返回我们自定义的页面
exc.description就是abort里面的第二个参数,错误描述

在这里插入图片描述

浏览器访问
在这里插入图片描述

2.当我们通过raise主动抛出一个我们自定义了错误类
在这里插入图片描述

此时,我们根据错误类型来捕获,并返回指定页面
在这里插入图片描述

浏览器访问
在这里插入图片描述

3.当我们打印一个不存在的变量,报NameError时
在这里插入图片描述

通过errorhandler捕获
在这里插入图片描述

浏览器访问,可以显示我们返回的页面内容
在这里插入图片描述

4.当我们访问一个不存在的url,我们捕获404报错,然后返回指定页面
在这里插入图片描述

浏览器访问
在这里插入图片描述

总结:
综上就是flask请求钩子的设置方式,以及在什么情况下用什么样的请求钩子,主动抛出异常的方式,对异常的捕获,返回更好看的异常显示页面等等,感兴趣的朋友可以一键三连,flask持续更新中!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/478815.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

头部银行 AI 落地实践|数据应用赋能经营管理闭环

数据要素在银行各业务领域和流程中发挥着至关重要的作用,面对激烈的市场竞争和客户需求,银行越来越注重从数据管理中寻求效益和增值,深入洞察市场动态和客户需求,从而优化其产品与服务,提升运营效率和市场营销的成效。…

《妈妈是什么》笔记(二) 让孩子自己做选择

经典摘录 孩子也会需要独立的空间做事情,求独立、求空间、求私隐 对于不管因为什么,别人在受到肯定和赞赏的时候,会对我们自己的心理带来因“比较”而产生的不适感甚至嫉妒感,进而在行为上影响了我们自己的节奏,产生一…

RabbitMQ是怎么做消息分发的?

标题RabbitMQ是怎么做消息分发的? RabbitMQ一共有6中工作模式(消息分发模式),分别是简单模式、工作队列模式、发布订阅模式、路由模式、主题模式、以及RPC模式。 简单模式是最基本的工作模式,也是最简单的消息传递模…

[Java、Android面试]_11_线程的启动方式和区别

文章目录 1. 继承Thread类2. 实现Runnable接口3. 实现Callable接口4. 使用Executor框架4. 四者的区别 本人今年参加了很多面试,也有幸拿到了一些大厂的offer,整理了众多面试资料,后续还会分享众多面试资料。 整理成了面试系列,由于…

DXP学习2- 绘制电气图【实验】

目录 一、实验目的 二、实验原理 1、创建一个新的项目文件。 2、新建原理图文件 3、设置原理图选项 4、放置元器件 5、其他电路元素的放置 6、对所有电路元素属性参数值的修改 三、实验设备 四、实验内容 1、绘制实验图2-1 元器件所在位置: 1,…

炒伦敦金大师级的交易技术

交易中的反身性由投资大师索罗斯提出,简单来说,它所描述的是投资者与市场之间那种奇妙的互动和互相影响的关系。大家可以把伦敦金市场趋势,想象成一个很大的舞台,它会影响和决定投资者的心理预期和决策。 而投资者的心理预期和决策…

【C++】Qt:WebSocket客户端示例

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍WebSocket客户端示例。 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新不迷路&…

k8s-kubectl命令详解、Pod创建过程、Pod的生命周期、定制Pod、资源对象文件

集群管理 一、如何管理集群 kubectl是用于管理Kubernetes集群的命令行工具 二、语法格式: kubectl [command] [TYPE] [NAME] [flags] command:子命令,如create,get,describe,delete type:…

redis集群数据一致性如何保证?

一般的做法是对key进行hash,比如有4台机器,就对4取模。 这样的坏处是增加或者减少机器的时候,会有大量数据进行迁移。 业界做法是用一致性哈希算法,将机器节点的ip值,对一个很大的数取模比如2^32, 用一个…

Prometheus 配置Basic auth认证

官方配置说明: Basic auth | Prometheus 一、生成密码加密串 Prometheus于2.24版本(包括2.24)之后提供Basic Auth功能进行加密访问,在浏览器登录UI的时候需要输入用户密码,访问Prometheus api的时候也需要加上用户密…

优质的短效HTTP代理具备什么优点?

随着网络时代的蓬勃发展,数据的获取与处理成为了企业决策和市场竞争的关键。在这场数据的角逐中,优质的短效HTTP代理脱颖而出,备受业界瞩目。优质的短效HTTP代理,提供了稳定的网络连接和匿名性,更为数据采集提供了关键…

Echarts组件初步封装

一、业务场景: 最近在vue中使用echarts时 有多处需要用到各种图表,想着自己封装一个便于多次复用 为了避免大家走弯路,为大家整理了一下,粘走可以直接用的那种 二、具体实现步骤: 1、先在终端安装echarts npm install…

管理类联考–复试–英文面试–问题--规划介绍原因做法--纯英文版

借鉴 https://www.bilibili.com/video/BV1Dk4y187zN/?p4&spm_id_from333.880.my_history.page.clickhttps://www.bilibili.com/video/BV1Dk4y187zN/?p4&spm_id_from333.880.my_history.page.click https://ttsreader.com/zh/https://ttsreader.com/zh/ 规划 视频版…

一文掌握Java动态代理的奥秘与应用场景

一、基本概念 为某个对象提供一个代理,以控制对这个对象的访问。代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象来替代。代理类负责请求的预处理、过滤、将请求分派委托类处理、以及委托类执行完请求后的后续处理。…

中国软件评测中心发布《健康软件安全白皮书》,美创参编分享方案实践

日前,中国软件评测中心网络安全和数据安全研究测评事业部发布《健康软件安全白皮书》研究成果,美创科技深度参与此次白皮书编写工作,针对健康软件目前面临的安全风险,分享数据安全建设思路。 白皮书详细剖析健康软件面临的网络和数…

盲盒抽卡机小程序:探索神秘盲盒,尽享抽卡乐趣

在盲盒文化的热潮中,盲盒抽卡机作为一种深受大众喜爱的娱乐形式,正逐渐成为市场上的新宠。为了满足广大盲盒爱好者和抽卡玩家的需求,我们积极投身于盲盒抽卡机小程序的开发,旨在通过创新的技术手段,为用户带来全新的盲…

PyTorch出现:RuntimeError: An attempt has been made to start a new process...报错

1.查看显卡: 第一步:同时按下键盘的winr键,输入cmd 第二步:随后输入 nvidia-smi 2.查看下载安装的包: conda list conda list 3.问题报错 PyTorch出现:RuntimeError: An attempt has been made to …

解决vue3中刷新浏览器页面的axios请求状态变为canceled

最近在开发中要加一个悲观锁的功能,具体需求是:用户1和用户2不能同时打开一个模型进行编辑,用户1优先进入模型后,要对该模型进行上锁,关闭该模型或刷新页面时要进行解锁,此时在刷新页面时出现了问题。 刷新…

线上linux服务器升级nginx

一个nginx版本空包 一个pcre文件 一个zlib文件 ./configure配置文件 make编译 make install复制所有文件到nginx 如果nginx -v无版本号 检查环境变量cat /etc/profile 编辑 环境变量vi /etc/profile 按i进入编辑模式 按esc进入查看模式 因为path中并未使用%JAVA_HOME%字样…

力扣---全排列---回溯

思路: 递归做法,一般会有visit数组来判断第 i 位是否被考虑了。我们先考虑第0位,再考虑第1位,再考虑第2位...dfs函数中还是老套路,先判定特殊条件,再从当下的角度(决定第 j 位是哪个元素&#x…