2011-11-15 7 views
8

Questa semplice applicazione, ha due teardown_request gestori, e mi aspetto ciascuno di essi di essere chiamato per ogni richiesta, non importa cosa succede nella realizzazione di vista, come per il documentationPerché viene chiamata una sola funzione teardown_request di Flask quando la vista solleva l'eccezione?

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) 

Tuttavia, quando ho eseguirlo e fare richieste ai tre punti di vista, a sua volta, ottengo il seguente output:

 
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 uno dei teardown_request funzioni viene chiamato quando un'eccezione che non è derivata da werkzeug.exceptions.HTTPException è sollevata dall'ultimo vista. Qualche idea del perché, o si tratta di un bug in fiaschetta?

risposta

20

Ho appena scoperto la risposta da solo.

Le funzioni teardown_request non devono rispondere e restituire una risposta, come fa after_request. Apparentemente accettano un argomento che di solito è None a meno che un punto HttpException non generato da HttpException venga generato dalla vista, nel qual caso viene passato.

A quanto pare anche non deve restituire l'eccezione o si otterrà il comportamento interrotto che ho dimostrato.

Per fissare, teardown_request funzioni della app dovrebbe essere simile a questo:

@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) 

Che poi dà l'uscita prevista per tutte e tre le viste:

 
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 l'aggiunta di un po 'di debug in più per stampa ciò che viene passato agli handler teardown_request)

+3

+1 - grazie anche per aver postato la risposta! –