【问题标题】:How to intercept all exceptions in flask?如何拦截烧瓶中的所有异常?
【发布时间】:2013-12-14 00:30:19
【问题描述】:

也许我在documentation 中没有看到任何内容。

我不仅想处理一些 http 错误,还想处理所有异常。原因 - 我想使用我自己的自定义逻辑来记录它们(听起来像是在重新发明轮子,但我需要完全控制日志记录。我不想让服务器在出现异常时屈服,而只轰炸那个特定的请求.

这就是我现在启动 Flask 的方式。这里app.run 启动服务器。我如何指示它在发生异常时调用我的异常处理程序方法?

def main():
    args = parse_args()
    app.config['PROPAGATE_EXCEPTIONS'] = True
    flask_options = {'port' : args.port}
    if args.host == 'public':
        flask_options['host'] = '0.0.0.0'
    app.run(**flask_options)

if __name__ == '__main__':
    _sys.exit(main())

【问题讨论】:

    标签: python-2.7 configuration exception-handling flask


    【解决方案1】:

    老问题,但对于 2021 年阅读的任何人:

    对于所有未明确定义的异常,可以返回 500 代码。

    该函数的结构来自 Flask cookiecutter,尽管该模式对每个错误都有一个 Jinja 模板。

    我没有运气自动捕获所有异常,但我发现这很DRYer,然后为每个单独的异常提供一个单独的页面。

    """
    app.exceptions
    ==============
    (python3)
    """
    # app/exceptions.py
    from typing import Tuple
    
    from flask import Flask, render_template
    from werkzeug.exceptions import HTTPException
    
    EXCEPTIONS = {
        400: "Bad Request",
        401: "Unauthorized",
        403: "Forbidden",
        404: "Not Found",
        405: "Method Not Allowed",
        500: "Internal Server Error",
    }
    
    
    # general function structure: https://github.com/cookiecutter-flask/cookiecutter-flask
    def init_app(app: Flask) -> None:
        """Register error handlers."""
    
        def render_error(error: HTTPException) -> Tuple[str, int]:
            """Render error template.
    
            If a HTTPException, pull the ``code`` attribute; default to 500.
    
            :param error: Exception to catch and render page for.
            :return: Tuple consisting of rendered template and error code.
            """
            app.logger.error(error.description)
            error_code = getattr(error, "code", 500)
            return (
                render_template(
                    "exception.html",
                    error_code=error_code,
                    exception=EXCEPTIONS[error_code],
                ),
                error_code,
            )
    
        for errcode in [400, 401, 403, 404, 405, 500]:
            app.errorhandler(errcode)(render_error)
    
    
    {# app/templates/exception.html #}
    {% extends "base.html" %}
    
    {# page header and browser tab #}
    {% block page_name %}{{ error_code }} {{ exception }}{% endblock %}
    

    【讨论】:

      【解决方案2】:

      试试这样的:

      @app.errorhandler(Exception)
      def all_exception_handler(error):
      
          return "Error: " + error.code
      

      【讨论】:

        【解决方案3】:

        您应该使用errorhandler,请参阅文档http://flask.pocoo.org/docs/patterns/errorpages/#error-handlershttp://flask.pocoo.org/docs/api/#flask.Flask.errorhandler。它允许您获取调度程序中引发的所有异常,但不处理错误处理程序中的异常。例如处理所有异常:

        @app.errorhandler(Exception)
        def all_exception_handler(error):
           return 'Error', 500
        

        对于这种情况,我更喜欢显式异常处理程序还是使用装饰器(基于类的视图)。

        【讨论】:

        • 这在最近的版本中不再起作用。在 0.12 中,我再次收到 HTML 错误页面。
        • @bwind 知道你应该如何在 0.12 中实现类似的逻辑吗?
        • @TuukkaMustonen:是的,请在此处查看我对另一个问题的回答:stackoverflow.com/questions/29332056/…
        猜你喜欢
        • 1970-01-01
        • 2016-03-14
        • 1970-01-01
        • 2014-07-19
        • 1970-01-01
        • 2018-07-24
        • 2011-05-13
        • 2020-09-11
        • 2010-09-18
        相关资源
        最近更新 更多