51

我喜欢 Flask 的错误捕捉。它非常简单:

@app.errorhandler(404)
def pageNotFound(error):
    return "page not found"

像魅力一样工作。但它不适用于 500 错误代码。当出现问题时,我想在代码中引发异常时捕获 Python 错误。那可能吗?

我应该注意,如果我return abort(500)在视图中明确调用,那么 500 错误处理程序确实可以工作。因此,这明确适用于 Python 代码失败的情况。

这可能吗?

4

6 回答 6

43

您所描述的是,默认情况下,Flask 是如何工作的。我的假设是您正在调试模式下运行,因此在调试屏幕中会向您显示异常。确保调试模式已关闭,然后重试。这是直接来自代码本身的评论:

当发生未捕获的异常时启动的默认异常处理。在调试模式下,异常将立即重新引发,否则将被记录并使用 500 内部服务器错误的处理程序。如果不存在这样的处理程序,则会显示默认的 500 内部服务器错误消息。

于 2013-02-21T14:22:19.087 回答
25

它在我身边工作正常:

from flask import Flask ,url_for,render_template,request,abort
from  werkzeug.debug import get_current_traceback
app = Flask(__name__)

@app.route('/')
def index():
    try:
        raise Exception("Can't connect to database")
    except Exception,e:
        track= get_current_traceback(skip=1, show_hidden_frames=True,
            ignore_system_exceptions=False)
        track.log()
        abort(500)
    return "index"

@app.errorhandler(500)
def internal_error(error):

    return "500 error"

@app.errorhandler(404)
def not_found(error):
    return "404 error",404

if __name__== "__main__":
    app.run(debug=True)

Flask 不会为您设置错误代码,因此请确保在返回响应时也提供 HTTP 状态代码。

于 2013-02-21T02:37:46.253 回答
20

这是我的代码片段

@app.route('/')
def index():
    raise Exception("Can't connect to database")


@app.errorhandler(Exception)
def exception_handler(error):
    return "!!!!"  + repr(error)
于 2015-02-26T09:13:01.423 回答
15

我对此的解决方案是通过修改配置字典来打开异常的传播:

app = Flask(__name__)
...
app.config['PROPAGATE_EXCEPTIONS'] = True

看看这个其他相关问题:Flask app raises a 500 error with no exception

于 2016-06-22T13:11:22.613 回答
4

问题在于,在代码中,并非所有 Exceptions 都是HTTPException,但 Flask 默认捕获这些并返回通用的 500 错误响应(可能包括也可能不包括 @Mark Hildreth 描述的原始错误消息)。因此, using@app.errorhandler(500)不会捕获这些错误,因为这发生在 Flask 返回通用 500 错误之前。

您需要有一个errorhandler(Exception)类似于except Exception:python 的泛型,它可以捕获所有内容。Flask 托盘项目提供了一个很好的解决方案:

from werkzeug.exceptions import HTTPException

@app.errorhandler(Exception)
def handle_exception(e):
    # pass through HTTP errors. You wouldn't want to handle these generically.
    if isinstance(e, HTTPException):
        return e

    # now you're handling non-HTTP exceptions only
    return render_template("500_generic.html", e=e), 500

如果您愿意,还可以返回 JSON,如果您处于调试模式,还可以包含原始错误消息。例如

from flask import jsonify
from werkzeug.exceptions import HTTPException

debug = True  # global variable setting the debug config

@app.errorhandler(Exception)
def handle_exception(e):
    if isinstance(e, HTTPException):
        return e

    res = {'code': 500,
           'errorType': 'Internal Server Error',
           'errorMessage': "Something went really wrong!"}
    if debug:
        res['errorMessage'] = e.message if hasattr(e, 'message') else f'{e}'

    return jsonify(res), 500
于 2020-05-23T20:23:27.857 回答
-1

此代码捕获 500 状态代码并获取异常错误

@app.errorhandler(Exception)
def all_exception_handler(e):
    error = str(traceback.format_exc())
于 2019-07-11T05:23:20.110 回答