2011-11-15 11 views
8

Esta sencilla aplicación, tiene dos teardown_request manipuladores, y yo esperaría que los dos para ser llamados para cada solicitud, no importa lo que sucede en la implementación de vista, según el documentation¿Por qué solo se llama a una función de petición de desmontaje de Flask cuando la vista genera una excepció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 ejecutarlo y hacer peticiones a los tres puntos de vista, a su vez, me sale 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 - 

Sólo se está llamando a uno de los teardown_request funciones cuando una excepción que no se deriva de werkzeug.exceptions.HTTPException se eleva por la última vista. ¿Alguna idea de por qué, o es esto un error en el matraz?

Respuesta

20

Acabo de descubrir la respuesta yo mismo.

Las funciones teardown_request no deben responder y responder, como lo hace after_request. Aparentemente toman un argumento que generalmente es None, a menos que la vista genere un Exception que no se deriva de HttpException, en cuyo caso se pasa eso.

Aparentemente también no debe devolver dicha excepción o obtendrá el comportamiento roto que he demostrado.

para fijar, teardown_request las funciones de la aplicación debe tener este aspecto:

@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 a su vez da la salida esperada para los tres puntos de vista:

 
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 un poco de depuración adicional para imprima lo que pasa a los controladores teardown_request)

+3

+1 - ¡Gracias por publicar la respuesta también! –

Cuestiones relacionadas