在Flask中捕获500服务器错误

J-b*_*bob 43 python flask

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

@app.errorhandler(404)
def pageNotFound(error):
    return "page not found"
Run Code Online (Sandbox Code Playgroud)

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

我应该注意,如果我return abort(500)在视图中明确调用那么500错误处理程序确实有效.所以这明确适用于Python代码失败的时候.

这可能吗?

Mar*_*eth 35

默认情况下,您所描述的是Flask的工作原理.我的假设是您在调试模式下运行,因此在调试屏幕中向您显示异常.确保调试模式已关闭,然后重试.以下是代码本身注释:

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

  • 你是对的,一旦我禁用了调试模式,它就起作用了。感谢您指出了这一点。我使用调试模式,以便当我在开发过程中进行更改时代码会自动重新加载。有没有办法在没有调试模式的情况下自动重新加载? (2认同)

Joe*_*Joe 23

它在我身边很好用:

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)
Run Code Online (Sandbox Code Playgroud)

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

  • 如果使用`DEBUG = True`它将不起作用(打印堆栈跟踪),它在开发时很舒服.因此,如果您想要查看真正的500页,请检查Flask应用程序是否在DEBUG模式下运行. (3认同)

Web*_*ube 17

这是我的代码snippt

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


@app.errorhandler(Exception)
def exception_handler(error):
    return "!!!!"  + repr(error)
Run Code Online (Sandbox Code Playgroud)


ela*_*ell 12

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

app = Flask(__name__)
...
app.config['PROPAGATE_EXCEPTIONS'] = True
Run Code Online (Sandbox Code Playgroud)

看看这个其他相关问题:Flask app引发了500错误,没有异常

  • 谢谢!!我正在撕开我的头发并添加这条线,最后在我的日志中"扔了一根骨头",这样我就可以搞清楚了.我讨厌500错误!为什么他们不把'错误:发生了什么';) (2认同)

Mak*_*kan 7

问题是,在代码中,并非所有异常都是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
Run Code Online (Sandbox Code Playgroud)

如果您愿意,还可以返回 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
Run Code Online (Sandbox Code Playgroud)