美文网首页Web开发——Flask框架
Flask框架——应用错误处理

Flask框架——应用错误处理

作者: 白巧克力LIN | 来源:发表于2022-08-05 01:23 被阅读0次

    上篇文章我们学习Flask框架——基于类的视图,这篇文章学习Flask框架——应用错误处理。
    即使我们的代码是百分百正确,但是还是会时常看见出错,这是因为和代码相关联的东西会出错,例如:

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

    除了这些错误还有很多错误,在生产环境下,我们通过把出错情况记录到日志里面。但这不是最好的处理错误方式。接下来我们学习更好的出错处理方式。

    错误日志工具

    当web应用程序运行发生错误时,我们可以通过日志文件来找错误信息并处理错误,但只要有足够多的用户触发了该错误或不同的错误,即使是很简单的错误,这样通过日志文件来找错误信息并处理错误就会变得很困难。

    这时我们可以使用Sentry来处理应用错误,Sentry可以统计重复错误、捕获堆栈数据和本地变量用于排错,并在发生新的错误时或按指定频度发送电子邮件。

    在使用Sentry时,执行如下代码安装flask依赖的sentry-sdk客户端:

    pip install sentry-sdk[flask]
    

    安装成功后,我们需要dsn值,dsn可以通过以下方式获取:

    1、进入sentry注册登录网站注册账号,如下图所示:


    这些注册信息可以随意填写,但Email和password需要我们记住,用来登录查看sentry发送的错误信息。

    2、创建项目,如下图所示:



    这里我们选择了flask,点击创建项目就会跳转到如下网页:



    我们通过官网提供的示例代码来演示如何使用sentry,代码如下所示:
    from flask import Flask
    import sentry_sdk
    from sentry_sdk.integrations.flask import FlaskIntegration
    sentry_sdk.init(                            #初始化配置
        dsn="YOUR_DSN_HERE",                     #设置dsn值
        integrations=[FlaskIntegration()],        #整合器
        traces_sample_rate=1.0                   #捕获的性能数据量,值在0-1之间
    )
    app = Flask(__name__)
    
    if __name__ == '__main__':
        app.run()
    

    首先导入sentry的库和方法,在进行sentry_sdk的初始化配置,接着编写一个视图函数,代码如下所示:

    @app.route('/debug-sentry')
    def trigger_error():
        division_by_zero = 1 / 0
    

    视图函数的语法没有问题,但由于0不能为被除数,所以当我们访问/debug-sentry的URL时,会触发一个错误,这个错误信息会被sentry捕获。

    运行flask程序,并访问http://127.0.0.1:5000/debug-sentry,如下图所示:

    该错误信息大概是说:服务器遇到内部错误,服务器过载或应用程序出错。

    登录sentry后,如下图所示:


    这样我们就成功捕获了错误信息和出错的次数了。

    错误处理器

    在Flask中发生错误时,会返回一个相应的HTTP状态码,状态码400499表示客户端的请求数据或与之相关的错误,状态码500599表示服务器或应用本身的错误。

    例如:在我们请求一个不存在的URL链接时,会发出一个404 Not Found错误,如下图所示:



    当发生错误时,向用户显示我们自定义的出错页面时,我们可以使用错误处理器。

    错误处理器是一个函数,类似视图函数的函数,当发生某类错误时,返回一个传递了正在处理的错误的实例响应。

    注册错误处理器

    在使用错误处理器时,需要先注册错误处理器,注册错误处理器有两种方法:使用errorhandler装饰函数注册、使用register_error_handler()来注册 ,示例代码如下:

    #使用装饰器函数注册
    @app.errorhandler(werkzeug.exceptions.BadRequest)       #传递子类BadRequest
    #@app.errorhandler(400)                   #或传递标准HTTP代码
    def handle_bad_request(e):
        return '错误请求', 400                  #返回出错代码400
        
    #使用register_error_handler()注册
    def handle_bad_request(e):
        return 'bad request!', 400              #返回出错代码400
    app.register_error_handler(400, handle_bad_request)
    

    在使用errorhandler装饰器函数注册时,需要传入werkzeug.exceptions.HTTPException的子类,例如BadRequest或者传递标准HTTP代码,如400,在返回响应时需要设置出错代码。

    自定义错误页面

    为了更能告诉用户错误信息,我们可以自定义错误页面,首先注册一个错误处理器器,再abort()函数,该函数可以中止请求,产生HTTP错误。Flask程序示例代码如下:

    import werkzeug
    from flask import Flask, abort
    app=Flask(__name__)
    
    @app.errorhandler(400)
    def handle_bad_request(e):
        return '错误请求', 400          #返回错误信息
    
    @app.route('/')
    def hello_world():
        abort(400)                      #使用abort()函数,传递400HTTP代码
    
    if __name__ == '__main__':
        app.run()
    

    启动Flask程序,访问http://127.0.0.1:5000/时,网页会显示错误请求。

    除了上面返回错误信息的数据格式,我们可以将错误信息以JSON的格式来返回,示例代码如下:

    from flask import Flask, abort,jsonify
    
    app=Flask(__name__)
    
    @app.errorhandler(404)                          #注册404错误处理器
    def resource_not_found(e):
        return jsonify(error=str(e)), 404            #使用jsonify()方法接收错误对象e,并传入错误HTML代码404
    
    @app.route('/')
    def hello_world():
        abort(404,description="Resource not found")          #抛出错误处理器错误信息
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    启动Flask程序,访问http://127.0.0.1:5000/时,网页会显示如下内容:

    {
      "error": "404 Not Found: Resource not found"
    }
    

    自定义错误处理器HTTP代码

    注意:Werkzeug 无法识别非标准HTTP代码,当返回出错代码不是标准的HTTP代码时,会报错,例如:返回出错代码1000

    KeyError: "'1000' is not a recognized HTTP error code. Use a subclass of HTTPException with that code instead."
    

    Werkzeug 无法识别非标准HTTP代码,也就是使用上面的方法无法注册非标准HTTP代码的错误处理器。

    这时我们自定义一个HTTPException子类, 注册并抛出异常类,Flask程序示例代码如下:

    import werkzeug
    from flask import Flask, abort, render_template
    
    app=Flask(__name__)
    
    class InsufficientStorage(werkzeug.exceptions.HTTPException):       #自定义HTTP错误子类
        code=1000
        description = 'Not enough storage space.'
    
    def handle_1000(e):
        return '服务器无法存储完成请求所必须的内容',1000                 #返回错误信息及HTTP代码
    app.register_error_handler(InsufficientStorage, handle_1000)          #注册错误处理器
    
    @app.route('/')
    def hello_world():
        raise InsufficientStorage()             #抛出错误处理器错误信息
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    这里我们创建了名为InsufficientStorage的子类,子类里面的内容可以是随意的,再创建一个名为handle_1000()的函数,该函数返回错误请求和HTTP代码。最后使用register_error_handler()方法注册错误处理器——InsufficientStorage子类和handle_507。

    启动Flask程序,访问http://127.0.0.1:5000/,如下图所示:

    通用错误处理器

    通用错误处理器就是把HTTP出错信息转换为JSON并展示在网页中,示例代码如下所示:

    import werkzeug
    from flask import Flask, abort, render_template
    from flask import json
    from werkzeug.exceptions import HTTPException
    
    app=Flask(__name__)
    
    @app.errorhandler(HTTPException)                #注册错误处理器
    def handle_exception(e):                       #错误处理器函数传入错误对象e
        response = e.get_response()                 #获取错误响应
        response.data = json.dumps({                #编辑错误响应内容
            "code": e.code,
            "name": e.name,
            "description": e.description,
        })
        response.content_type = "application/json"   #设置响应类型
        return response
    
    @app.route('/')
    def hello_world():
        abort(501)                              #使用abort()传入501错误代码
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    首先使用errorhandler装饰器注册错误处理器,并定义错误处理器函数接收错误对象e,根据错误对象e来编辑返回错误响应内容。

    启动Flask程序,访问http://127.0.0.1:5000/,如下图所示:

    好了,Flask框架——应用错误处理就学到这里了,感谢观看,下篇文章我们继续学习Flask框架——Bootstrap-Flask使用。

    公众号:白巧克力LIN

    该公众号发布Python、数据库、Linux、Flask、自动化测试、Git等相关文章!

    相关文章

      网友评论

        本文标题:Flask框架——应用错误处理

        本文链接:https://www.haomeiwen.com/subject/dtguwrtx.html