Python 如何为Flask中的所有HTTP错误实现自定义错误处理程序?

Python 如何为Flask中的所有HTTP错误实现自定义错误处理程序?,python,error-handling,flask,python-decorators,Python,Error Handling,Flask,Python Decorators,在我的Flask应用程序中,通过为每个错误代码添加errorhandlerdecorators,我可以轻松地扩展单个自定义错误处理程序处理的错误列表 @application.errorhandler(404) @application.errorhandler(401) @application.errorhandler(500) def http_error_handler(error): return flask.render_template('error.html', erro

在我的Flask应用程序中,通过为每个错误代码添加
errorhandler
decorators,我可以轻松地扩展单个自定义错误处理程序处理的错误列表

@application.errorhandler(404)
@application.errorhandler(401)
@application.errorhandler(500)
def http_error_handler(error):
    return flask.render_template('error.html', error=error), error.code

然而,这种方法要求每个错误代码都有一个显式的修饰符。有没有一种方法可以修饰我的(单个)
http\u error\u handler
函数,使其能够处理所有http错误?

你不是唯一的一个,一个解决方法是指定你捕获并绑定到应用程序的http错误代码列表。error\u handler\u spec,然后删除修饰程序,如下所示:

def http_error_handler(error):
    return flask.render_template('error.html', error=error), error.code

for error in (401, 404, 500): # or with other http code you consider as error
    application.error_handler_spec[None][error] = http_error_handler

我知道这并不理想,也不丑陋,但它会起作用,我真的希望其他人能拿出更好的解决方案。希望这能有所帮助。

您可以将
errorhandler
装饰器与异常类一起使用,而不是将错误代码作为参数,如前所述。例如,你可以试试看

@application.errorhandler(HTTPException)
def http_error_handler(error):
处理所有HTTP错误(可能意味着所有HTTP错误代码),甚至

处理所有未捕获的异常

编辑:查看flask源代码后,在应用程序配置中有一个“TRAP\u HTTP\u EXCEPTIONS”标志,您可以对其进行更改(例如执行
app.config['TRAP\u HTTP\u EXCEPTIONS']=True

(大致上)当此标志为false时,作为HTTPException实例的异常由您用
errorhandler(n)
修饰的函数处理,其中
n
是HTTP错误代码;当这个标志为true时,HTTPException的所有实例都由您用
errorhandler(c)
修饰的函数来处理,其中c是一个异常类

这样做

app.config['TRAP_HTTP_EXCEPTIONS']=True

@application.errorhandler(Exception)
def http_error_handler(error):
你应该实现你想要的

由于HTTPException似乎对每个HTTP错误代码都有子类(请参阅),因此设置“TRAP_HTTP_EXCEPTIONS”并用异常类而不是错误代码装饰错误处理程序看起来是一种更为灵活的方法

作为参考,我的烧瓶错误处理现在如下所示:

app.config['TRAP_HTTP_EXCEPTIONS']=True

@app.errorhandler(Exception)
def handle_error(e):
    try:
        if e.code < 400:
            return flask.Response.force_type(e, flask.request.environ)
        elif e.code == 404:
            return make_error_page("Page Not Found", "The page you're looking for was not found"), 404
        raise e
    except:
        return make_error_page("Error", "Something went wrong"), 500
app.config['TRAP\u HTTP\u EXCEPTIONS']=True
@app.errorhandler(异常)
def句柄_错误(e):
尝试:
如果e.code<400:
返回烧瓶。响应。强制类型(e,烧瓶。请求。环境)
elif e.code==404:
返回make_error_页面(“未找到页面”,“未找到您要查找的页面”),404
提高e
除:
返回make_error_页面(“错误”,“出了问题”),500

这做了我想要的一切,并且似乎可以处理所有错误,包括HTTP和内部错误。
如果e.code<400
位用于将flask的默认行为用于重定向等(否则这些行为最终会导致错误500s,这不是您想要的)

对于我来说,以下代码段不起作用:

@app.errorhandler(HTTPException)
def _handle_http_exception(e):
    return make_response(render_template("errors/http_exception.html", code=e.code, description=e.description), e.code)
但是将
HTTPException
更改为真实的异常(如
NotFound
)是可行的。别问我为什么,我没找到答案

因此,我找到了另一种非常有效的解决方案:

from werkzeug.exceptions import default_exceptions

def _handle_http_exception(e):
    return make_response(render_template("errors/http_exception.html", code=e.code, description=e.description), e.code)

for code in default_exceptions:
    app.errorhandler(code)(_handle_http_exception)

(位于)

是的,谢谢。我看到了这一点,希望避免(a)列出和(b)使用
错误处理程序\u规范
。(现在)这真的是唯一的方法吗?@raxacoricofallapatorius,我确实遇到了同样的问题,经过相当多的研究(可能像你已经做的那样),这是我目前认为的唯一方法。其他的装饰方法不知何故不会引发错误,或者您需要有目的地引发异常,这看起来更糟糕。我想知道设计的原因是什么(或者它是否只是一个遗漏)。@Raxacoricoffallapatorius,我认为这更可能是根据Flask的形式判断的设计不会处理错误代码状态,除非明确定义。我在Python3中用PIP存储库中最新的Flask尝试了这一点。结果没有成功。知道为什么吗?在这种情况下,HTTPException抛出的代码<400?我检查了Werkzeug代码(),所有属于HTTPException子类的异常都有一个大于等于400的代码?我已经很久没有考虑过这个问题了,在实践中,代码小于400的情况可能是不必要的,但理论上这是为了处理重定向等(如回答的最后一段所讨论的)这对我很有帮助。非常感谢。
from werkzeug.exceptions import default_exceptions

def _handle_http_exception(e):
    return make_response(render_template("errors/http_exception.html", code=e.code, description=e.description), e.code)

for code in default_exceptions:
    app.errorhandler(code)(_handle_http_exception)