diff --git a/docs/patterns/sqlite3.rst b/docs/patterns/sqlite3.rst index bc471f66..0d02e465 100644 --- a/docs/patterns/sqlite3.rst +++ b/docs/patterns/sqlite3.rst @@ -24,7 +24,15 @@ So here is a simple example of how you can use SQLite 3 with Flask:: @app.teardown_request def teardown_request(exception): - g.db.close() + if hasattr(g, 'db'): + g.db.close() + +.. note:: + + Please keep in mind that the teardown request functions are always + executed, even if a before-request handler failed or was never + executed. Because of this we have to make sure here that the database + is there before we close it. Connect on Demand ----------------- diff --git a/docs/reqcontext.rst b/docs/reqcontext.rst index 3b49e1d5..0249b88e 100644 --- a/docs/reqcontext.rst +++ b/docs/reqcontext.rst @@ -131,7 +131,9 @@ understand what is actually happening. The new behavior is quite simple: 4. At the end of the request the :meth:`~flask.Flask.teardown_request` functions are executed. This always happens, even in case of an - unhandled exception down the road. + unhandled exception down the road or if a before-request handler was + not executed yet or at all (for example in test environments sometimes + you might want to not execute before-request callbacks). Now what happens on errors? In production mode if an exception is not caught, the 500 internal server handler is called. In development mode @@ -183,6 +185,12 @@ It's easy to see the behavior from the command line: this runs after request >>> +Keep in mind that teardown callbacks are always executed, even if +before-request callbacks were not executed yet but an exception happened. +Certain parts of the test system might also temporarily create a request +context without calling the before-request handlers. Make sure to write +your teardown-request handlers in a way that they will never fail. + .. _notes-on-proxies: Notes On Proxies diff --git a/docs/upgrading.rst b/docs/upgrading.rst index 13b5be71..b318292c 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -142,7 +142,8 @@ You are now encouraged to use this instead:: @app.teardown_request def after_request(exception): - g.db.close() + if hasattr(g, 'db'): + g.db.close() On the upside this change greatly improves the internal code flow and makes it easier to customize the dispatching and error handling. This diff --git a/examples/flaskr/flaskr.py b/examples/flaskr/flaskr.py index 361c1aee..6f9b06fc 100644 --- a/examples/flaskr/flaskr.py +++ b/examples/flaskr/flaskr.py @@ -50,7 +50,8 @@ def before_request(): @app.teardown_request def teardown_request(exception): """Closes the database again at the end of the request.""" - g.db.close() + if hasattr(g, 'db'): + g.db.close() @app.route('/') diff --git a/examples/minitwit/minitwit.py b/examples/minitwit/minitwit.py index f7c700d3..fee023fd 100644 --- a/examples/minitwit/minitwit.py +++ b/examples/minitwit/minitwit.py @@ -85,7 +85,8 @@ def before_request(): @app.teardown_request def teardown_request(exception): """Closes the database again at the end of the request.""" - g.db.close() + if hasattr(g, 'db'): + g.db.close() @app.route('/')