10

这个简单的应用程序有两个teardown_request处理程序,我希望每个请求都调用它们,无论视图实现中发生什么,根据文档

import flask
import werkzeug.exceptions

app = flask.Flask(__name__)

@app.teardown_request
def teardown1(response):
    print "Teardown 1"
    return response

@app.teardown_request
def teardown2(response):
    print "Teardown 2"
    return response

@app.route("/")
def index():
    return "chunky bacon"

@app.route("/httpexception")
def httpexception():
    raise werkzeug.exceptions.BadRequest("no bacon?")

@app.route("/exception")
def exception():
    raise Exception("bacoff")

if __name__ == "__main__":
    app.run(port=5000)

但是,当我运行它并依次向三个视图发出请求时,我得到以下输出:

拆解 2
拆解 1
127.0.0.1 - - [2011 年 11 月 15 日 18:53:16] “GET / HTTP/1.1” 200 -

拆解 2
拆解 1
127.0.0.1 - - [2011 年 11 月 15 日 18:53:27] “GET /httpexception HTTP/1.1”400 -

拆解 2
127.0.0.1 - - [2011 年 11 月 15 日 18:53:33] “GET /异常 HTTP/1.1”500 -

当最后一个视图引发teardown_request非派生异常时,仅调用其中一个函数。werkzeug.exceptions.HTTPException任何想法为什么,或者这是烧瓶中的错误?

4

1 回答 1

24

刚刚自己发现了答案。

这些teardown_request函数不应该接受响应并返回响应,方式after_request确实如此。他们显然采用了一个论点,该论点通常是None,除非视图提出了一个Exception不是源自HttpException的论点,在这种情况下,他们被传递了那个论点。

显然他们也不能返回所说的异常,否则你会得到我展示的破坏行为。

要修复,应用程序的teardown_request功能应如下所示:

@app.teardown_request
def teardown1(exc):
    print "Teardown 1 {0!r}".format(exc)

@app.teardown_request
def teardown2(exc):
    print "Teardown 2 {0!r}".format(exc)

然后给出所有三个视图的预期输出:

拆解 2 无
拆解 1 无
127.0.0.1 - - [2011 年 11 月 15 日 19:20:03] “GET / HTTP/1.1” 200 -

拆解 2 无
拆解 1 无
127.0.0.1 - - [2011 年 11 月 15 日 19:20:10] “GET /httpexception HTTP/1.1”400 -

拆解 2 异常('bacoff',)
拆解 1 异常('bacoff',)
127.0.0.1 - - [2011 年 11 月 15 日 19:20:18] “GET /异常 HTTP/1.1”500 -

(添加了一些额外的调试来打印传递给teardown_request处理程序的内容)

于 2011-11-15T19:56:30.497 回答