python - example - ¿Por qué solo se llama a una función de petición de desmontaje de Flask cuando la vista genera una excepción?
werkzeug traduccion (1)
Acabo de descubrir la respuesta yo mismo.
Se supone que las funciones de recuperación de datos no toman una respuesta y devuelven una respuesta, como after_request
hace after_request
. Aparentemente toman un argumento que normalmente es None
menos que la vista HttpException
una Exception
que no se deriva de HttpException
, en cuyo caso se pasan por eso.
Aparentemente ellos tampoco deben devolver dicha excepción o obtendrás el comportamiento roto que demostré.
Para solucionarlo, las funciones de teardown_request
de teardown_request
la aplicación deberían verse así:
@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)
Que luego da el resultado esperado para las tres vistas:
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 -
(con la adición de una depuración adicional para imprimir lo que pasa a los controladores teardown_request
)
Esta sencilla aplicación tiene dos controladores de teardown_request
demanda, y espero que se llamen a ambos para cada solicitud, sin importar lo que ocurra en la implementación de la vista, según la documentación
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)
Sin embargo, cuando lo ejecuto y realizo solicitudes a las tres vistas, obtengo el siguiente resultado:
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 -
Solo se llama a una de las funciones de werkzeug.exceptions.HTTPException
de werkzeug.exceptions.HTTPException
cuando una última excepción muestra una excepción que no se deriva de werkzeug.exceptions.HTTPException
. ¿Alguna idea de por qué, o es esto un error en el matraz?