目录

  • Flask 应用错误处理

    • 错误日志工具
    • 错误处理
      • 注册
      • 处理
    • 日志
  • 排除应用错误
    • 有疑问时,请手动运行
    • 使用调试器
    • 参考

Flask 应用错误处理

应用出错,服务器出错。或早或晚,你会遇到产品出错。即使你的代码是百分百正确, 还是会时常看见出错。为什么?因为其他相关东西会出错。以下是一些在代码完全正确的 条件下服务器出错的情况:

  • 客户端已经中断了请求,但应用还在读取数据。
  • 数据库已经过载,无法处理查询。
  • 文件系统没有空间。
  • 硬盘完蛋了。
  • 后台服务过载。
  • 使用的库出现程序错误。
  • 服务器与另一个系统的网络连接出错。

以上只是你会遇到的问题的一小部分。那么如何处理这些问题呢?如果你的应用运行 在生产环境下,那么缺省情况下 Flask 会显示一个简单的出错页面,并把出错情况 记录到 logger

但可做的还不只这些,下面介绍一些更好的出错处理方法。

错误日志工具

当足够多的用户触发了错误时,发送关于出错信息的邮件,即使仅包含严重错误的邮件也会是一场灾难。更不用提从来不会去看的日志文件了。 因此,推荐使用 Sentry 来处理应用错误。它可 以在一个开源项目 on GitHub 中获得, 也可以在 hosted version 中免费试用。 Sentry 统计重复错误,捕获堆栈数据和本地变量用于排错,并在发生新的或者指定频度的错误时发送电子邮件。

  • Sentry顾名思议,翻译过来是哨兵的意思。
  • 它可以监控我们在生产环境中项目的运行状态,一旦某段代码运行报错,或者异常,会第一时间把报错的 路由异常文件请求方式 等一些非常详细的信息以消息或者邮件给我们,让我们第一时间知道:程序出错了,继而从 Sentry 给出的详细的错误信息中瞬间找到需要处理的代码,尽快把 Bug 修复。

  • Sentry是一个实时的事件日志和聚合平台。
  • Sentry 可以帮助你将程序的所有 exception 自动记录下来,处理 exception 是每个程序的必要部分,有利于我们开发。
  • 如果试用 Sentry 官方提供的服务是需要收费的,不过可以免费试用,当然最好还是自己搭建 Sentry :文档 自行搭建当然就不收费啦。
  • 官网安装和使用参考
  • Docker 安装 Here,Python 安装 Here

要使用 Sentry 需要安装带有 flask 依赖的 raven 客户端:

$ pip install raven[flask]
(venv) E:\Flask\myproject>pip install raven[flask]
Collecting raven[flask]Downloading https://files.pythonhosted.org/packages/11/3a/b3e46b279b8bdd9eb55857d0e95044cad31732c80f628bb75e1e9e881a32
/raven-6.9.0-py2.py3-none-any.whl (287kB)100% |████████████████████████████████| 296kB 4.3kB/s
Requirement already satisfied: Flask>=0.8; extra == "flask" in e:\flask\myproject\venv\lib\site-packages (from raven[fla
sk]) (1.0.2)
Collecting blinker>=1.1; extra == "flask" (from raven[flask])Downloading https://files.pythonhosted.org/packages/1b/51/e2a9f3b757eb802f61dc1f2b09c8c99f6eb01cf06416c0671253536517b6
/blinker-1.4.tar.gz (111kB)100% |████████████████████████████████| 112kB 8.7kB/s
Requirement already satisfied: Jinja2>=2.10 in e:\flask\myproject\venv\lib\site-packages (from Flask>=0.8; extra == "fla
sk"->raven[flask]) (2.10)
Requirement already satisfied: itsdangerous>=0.24 in e:\flask\myproject\venv\lib\site-packages (from Flask>=0.8; extra =
= "flask"->raven[flask]) (0.24)
Requirement already satisfied: click>=5.1 in e:\flask\myproject\venv\lib\site-packages (from Flask>=0.8; extra == "flask
"->raven[flask]) (6.7)
Requirement already satisfied: Werkzeug>=0.14 in e:\flask\myproject\venv\lib\site-packages (from Flask>=0.8; extra == "f
lask"->raven[flask]) (0.14.1)
Requirement already satisfied: MarkupSafe>=0.23 in e:\flask\myproject\venv\lib\site-packages (from Jinja2>=2.10->Flask>=
0.8; extra == "flask"->raven[flask]) (1.0)
Installing collected packages: blinker, ravenRunning setup.py install for blinker ... done
Successfully installed blinker-1.4 raven-6.9.0

把下面内容加入 Flask 应用:

from raven.contrib.flask import Sentry
sentry = Sentry(app, dsn='YOUR_DSN_HERE')

或者,如果使用了工厂,那么可以在稍后初始化:

from raven.contrib.flask import Sentry
sentry = Sentry(dsn='YOUR_DSN_HERE')def create_app():app = Flask(__name__)sentry.init_app(app)...return app

YOUR_DSN_HERE 需要被替换为在 Sentry 安装时获得的 DSN 值。

注:关于DSN值,详情可参考Sentry自动化异常提醒一文。

简单的说就是你安装Sentry后,配置文件中 dsn 就在我们看的文档下方,每个用户的 dsn 都是唯一的,在你的项目中配置了 dsn ,Sentry 就能监控你的项目。

之后,服务信息会自动向 Sentry 报告,你就可以接收到出错通知。

错误处理

当错误发生时,你可能想要向用户显示自定义的出错页面。注册出错处理器来做到这点。

一个出错处理器是一个返回响应的普通视图函数。

但是不同之在于它不是用于路由的 ,而是用于一个异常或者当尝试处理请求时抛出 HTTP 状态码。

注册

通过使用 errorhandler() 装饰函数来注册或者稍后使用 register_error_handler() 来注册。 记得当返回响应的时候设置出错代码:

@app.errorhandler(werkzeug.exceptions.BadRequest)
def handle_bad_request(e):return 'bad request!', 400# or, without the decorator
app.register_error_handler(400, handle_bad_request)

当注册时, werkzeug.exceptions.HTTPException 的子类,如 BadRequest ,和它们的 HTTP 代码是可替换的。 ( BadRequest.code == 400

因为 Werkzeug 无法识别非标准 HTTP 代码,因此它们不能被注册。替代地,使用适当的代码定义一个 HTTPException 子类,注册并抛出异常类:

class InsufficientStorage(werkzeug.exceptions.HTTPException):code = 507description = 'Not enough storage space.'app.register_error_handler(InsuffcientStorage, handle_507)raise InsufficientStorage()

出错处理器可被用于任何异常类的注册,除了 HTTPException 子类或者 HTTP 状态码。 出错处理器可被用于特定类的注册,也可用于一个父类的所有子类的注册。

处理

在处理请求时,当 Flask 捕捉到一个异常时,它首先根据代码检索。如果该代码没 有注册处理器,它会根据类的继承来查找,确定最合适的注册处理器。如果找不到已 注册的处理器,那么 HTTPException 子类会显示 一个关于代码的通用消息。没有代码的异常会被转化为一个通用的 500 内部服务器 错误。

例如,如果一个 ConnectionRefusedError 的实例被抛出,并且一个出错处 理器注册到 ConnectionErrorConnectionRefusedError ,那么 会使用更合适的 ConnectionRefusedError 来处理异常实例,生成响应。

当一个蓝图在处理抛出异常的请求时,在蓝图中注册的出错处理器优先于在应用中全 局注册的出错处理器。但是,蓝图无法处理 404 路由错误,因为 404 发生的路由级 别还不能检测到蓝图。

日志

如何记录异常,比如向管理者发送邮件,参见 日志 。

排除应用错误

应用错误处理 一文所讲的是如何为生产应用设置日志和出错通知。本文要讲的是部署中配置调试的要点和如何使用全功能的 Python 调试器深挖错误。

有疑问时,请手动运行

在生产环境中,配置应用时出错?

  • 如果你可以通过 shell 来访问主机,那么首先请在部署环境中验证是否可以通过 shell 手动运行你的应用。

  • 请确保验证时使用的帐户与配置的相同,这样可以排除用户权限引发的错误。

  • 可以在你的生产服务器上, 使用 Flask 内建的开发服务器,并且设置 debug=True ,这样有助于找到配置问 题。但是,请 只在可控的情况下临时这样做 ,绝不能在生产时使用 debug=True

使用调试器

为了更深入的挖掘错误,追踪代码的执行, Flask 提供一个开箱即用的调试器(参 见 调试模式 )。如果你需要使用其他 Python 调试器,请注意调试器之 间的干扰问题。在使用你自己的调试器前要做一些参数调整:

  • debug - 是否开启调试模式并捕捉异常
  • use_debugger - 是否使用 Flask 内建的调试器
  • use_reloader - 出现异常后是否重载或者派生进程

debug 必须设置为 True (即必须捕获异常),另两个随便。

如果你正在使用 Aptana 或 Eclipse 排错,那么 use_debuggeruse_reloader 都必须设置为 False 。

一个有用的配置模式如下(当然要根据你的应用调整缩进):

FLASK:DEBUG: TrueDEBUG_WITH_APTANA: True

然后,在应用入口( main.py ),修改如下:

if __name__ == "__main__":# To allow aptana to receive errors, set use_debugger=Falseapp = create_app(config="config.yaml")if app.debug: use_debugger = Truetry:# Disable Flask's debugger if external debugger is requesteduse_debugger = not(app.config.get('DEBUG_WITH_APTANA'))except:passapp.run(use_debugger=use_debugger, debug=app.debug,use_reloader=use_debugger, host='0.0.0.0')

参考

  • 本文大部分引用自Flask中文文档

我在它的基础上加入了一些命令的反馈和一些插件更具体的描述等。

  • Sentry自动化异常提醒

转载于:https://www.cnblogs.com/tielemao/p/9600966.html

Flask应用错误处理相关推荐

  1. Flask自定义错误页面的方法

    无论再完善的项目,总会在实际使用中冒出几个bug,有的bug是可控的,有的无法避免,如404,本身这个页面不存在.那么这个时候展示一个没有经过处理的错误页面显得有点不专业,我们通常会把常见的可预见性的 ...

  2. Flask常见错误与解决方法

    1.ValueError: urls must start with a leading slash 这个错误原因可能发生在所有路由相关地方,少加了一个'/'造成的. 2.ImportError: c ...

  3. flask出现错误:cannot import name ‘ContextVar‘

    不能装flask 2.0.0 安装flask==1.0.2 然后再重装werkzeug 所以应该先:pip install flask==1.0.2 然后再 pip install werkzeug ...

  4. flask 自定义错误页面

    当服务器接受了不可用路由时,返回404状态码,这时就可以通过 @app.errorhandler(404) 自定义错误的状态码 比如 @app.errorhandler(404) def page_n ...

  5. Pycharm安装FLASK出现错误,无法安装

    问题描述:本来照着一个教程学习,之前安装插件都可以正常安装,在新创建Flask工程时出现无法安装成功,提示pip版本不对等等,但是我之前安装其他插件都可以正常安装 解决办法:在之前学习的Python工 ...

  6. 关于flask的错误:ImportError: cannot import name 'Flask'

    刚接触Flask的时候,运行python脚本如下: from flask import Flaskapp = Flask(__name__)@app.route("/") def ...

  7. Flask框架后端开发常见错误处理(2018/11/14)

    Flask常见错误与解决方法(By Wdx) 1.ValueError: urls must start with a leading slash 这个错误原因可能发生在所有路由相关地方,少加了一个' ...

  8. 使用Flask搭建一个校园论坛3-登录注册

    简介 在上一节中,主要介绍了项目入口怎么实现,同时基于jinja2提供的模板继承功能完成了基模板的编写,同时使用flask的错误处理装饰器完成了继承自基模板的错误页面自定义.在本章节中,将介绍用户注册 ...

  9. python3.6虚拟环境以及flask的安装(常见问题)

    准备基于python进行web应用开发 Python3.3以上的版本通过venv模块原生支持虚拟环境,可以代替Python之前的virtualenv. 该venv模块提供了创建轻量级"虚拟环 ...

  10. flask使用debug模式时,存在错误时,会占用设备内存直至服务重启才释放;debug模式会开启一个守护进程(daemon process)...

    函数调用顺序flask的app.py的run-->werkzeug的serving.py的run_simple-->调用werkzeug的debug的__init__.py里的类Debug ...

最新文章

  1. Android 基本面试题
  2. python约束 与MD5加密写法
  3. ASP.NET MVC获取上传的路径
  4. java 替换多个字符串_Java一次(或以最有效的方式)替换字符串中的多个不同子字符串...
  5. c语言数组如何把一串数字存入数组_C语言经典编程题(下)
  6. Window下更新python pip源
  7. DataSet.Tables[].Rows[][]的用法
  8. 本泽马梅开二度瓦拉内染红 10人皇马4:2客胜西班牙人
  9. 6款字体转换工具网站,一键生成想要字体!
  10. Python学习笔记 使用matplotlib创建Gif动图
  11. 2021牛客暑期多校训练营#5:C-Cheating and Stealing
  12. php处理excel里面的重复数据,表格中删除重复项怎么操作
  13. python可视化是什么意思_python3数据可视化是什么?
  14. 利用ajax从jsp中返回的字符串时出现回车符号解决办法
  15. 电脑睡眠后启动 耳机没有声音 手动启动 -已解决
  16. Python自学笔记1(think python)
  17. 用计算机管理员同步一下文件,《计算机应用基础(Windows 7 Office 2010)同步训练》0711.docx...
  18. 根据电话号码获取联系人姓名
  19. perl实现数组间的组合
  20. 北京公务员计算机试题,北京公务员补录一级计算机练习题计算机一级计算机基础及+MS+Office应用(选择题)模拟试卷190:钢铁是怎样炼成的读后感...

热门文章

  1. 3.2生产者和消费者(Producers and Consumers)
  2. 协同过滤推荐算法-----向量之间的相似度
  3. JavaScript中的数据类型和数据类型转换
  4. freeswitch 一些坑
  5. 俞昆20155335《网络对抗》MSF基础应用
  6. 知识、经验的漏洞还有很多很多
  7. 【转】Roberts 算子
  8. 【转】Java 学习杂谈(二)
  9. bug-箭头函数中this指向的问题
  10. lintcode-medium-Longest Common Substring