Day*_*Day 9 python werkzeug flask
这个简单的应用程序有两个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)
Run Code Online (Sandbox Code Playgroud)
但是,当我运行它并依次向三个视图发出请求时,我得到以下输出:
Teardown 2 Teardown 1 127.0.0.1 - - [15/Nov/2011 18:53:16] "GET / HTTP/1.1" 200 - Teardown 2 Teardown 1 127.0.0.1 - - [15/Nov/2011 18:53:27] "GET /httpexception HTTP/1.1" 400 - Teardown 2 127.0.0.1 - - [15/Nov/2011 18:53:33] "GET /exception HTTP/1.1" 500 -
teardown_request当werkzeug.exceptions.HTTPException最后一个视图引发未派生的异常时,只调用其中一个函数.任何想法为什么,或者这是烧瓶中的错误?
Day*_*Day 21
刚刚发现了答案.
这样的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)
Run Code Online (Sandbox Code Playgroud)
然后,它给出了所有三个视图的预期输出:
Teardown 2 None
Teardown 1 None
127.0.0.1 - - [15/Nov/2011 19:20:03] "GET / HTTP/1.1" 200 -
Teardown 2 None
Teardown 1 None
127.0.0.1 - - [15/Nov/2011 19:20:10] "GET /httpexception HTTP/1.1" 400 -
Teardown 2 Exception('bacoff',)
Teardown 1 Exception('bacoff',)
127.0.0.1 - - [15/Nov/2011 19:20:18] "GET /exception HTTP/1.1" 500 -
(添加了一些额外的调试来打印传递给teardown_request处理程序的内容)