Issue 1:
Expected Behavior

auto_pop of the request context should be executed regardless of whether an exception happened after pushing the context(for example, when opening a session).

We're using Redis sessions from flask_session:

def _setup_session(app):
from util.cache.region import cache_region
from dogpile.cache.backends.null import NullBackend
from flask_session import RedisSessionInterface

if not isinstance(cache_region.backend, NullBackend):
redis = cache_region.backend.client
session_interface = RedisSessionInterface(redis, 'test.session.', use_signer=False, permanent=False)
app.session_interface = session_interface

Actual Behavior

The request context is not popped whenever there is a timeout getting the session from Redis.

We can see in following requests the 'g' object still holds information from the failing request.

In ctx.py the context is first pushed and then the session is opened:

_request_ctx_stack.push(self)

# Open the session at the moment that the request context is
# available. This allows a custom open_session method to use the
# request context (e.g. code that access database information
# stored on `g` instead of the appcontext).
self.session = self.app.open_session(self.request)

But if open_session() fails, then ctx.auto_pop() is not executed. Perhaps ctx.push() should also be under the try...finally block in app.py?

This is the exception that triggers the context not to be popped:

redis.exceptions:TimeoutError: Timeout reading from socket
Traceback (most recent call last):
File "/var/www/censored_production/env/lib/python2.7/site-packages/newrelic-2.74.0.54/newrelic/api/web_transaction.py", line 738, in __iter__
File "/var/www/censored_production/env/lib/python2.7/site-packages/newrelic-2.74.0.54/newrelic/api/web_transaction.py", line 1114, in __call__
File "/var/www/censored_production/env/lib/python2.7/site-packages/werkzeug/contrib/fixers.py", line 152, in __call__
File "/var/www/censored_production/www/censored/util/logging.py", line 136, in __call__
File "/var/www/censored_production/env/lib/python2.7/site-packages/flask/app.py", line 1813, in wsgi_app
File "/var/www/censored_production/env/lib/python2.7/site-packages/flask/ctx.py", line 321, in push
File "/var/www/censored_production/env/lib/python2.7/site-packages/flask/app.py", line 825, in open_session
File "/var/www/censored_production/env/lib/python2.7/site-packages/flask_session/sessions.py", line 132, in open_session
File "/var/www/censored_production/env/lib/python2.7/site-packages/newrelic-2.74.0.54/newrelic/hooks/datastore_redis.py", line 67, in _nr_wrapper_Redis_method_
File "/var/www/censored_production/env/lib/python2.7/site-packages/redis/client.py", line 880, in get
File "/var/www/censored_production/env/lib/python2.7/site-packages/redis/client.py", line 573, in execute_command
File "/var/www/censored_production/env/lib/python2.7/site-packages/redis/client.py", line 585, in parse_response
File "/var/www/censored_production/env/lib/python2.7/site-packages/redis/connection.py", line 577, in read_response
File "/var/www/censored_production/env/lib/python2.7/site-packages/redis/connection.py", line 238, in read_response
File "/var/www/censored_production/env/lib/python2.7/site-packages/redis/connection.py", line 168, in readline
File "/var/www/censored_production/env/lib/python2.7/site-packages/redis/connection.py", line 139, in _read_from_socket

Environment

Python version: 2.7.6

Flask version: 0.10.1

Werkzeug version: 0.11.11

Issue 2:
RequestContext push is called in wsgi_app method, outside try..finally block. In push() method application's open_session call takes place, which can possibly lead to exception. But, since original call is not in try..finally block, removal of stack top never takes place. This leads to following problems:

1. Application context stack never updates again

RequestContext.push() only checks that application context exists or belongs to current application, but same rules apply to previous context.

2. Request context stack grows

Again, request context stack is pushed, but never removed. Actually just a memory leak :)

3. Misleading code comment about open_session usage

Inspired by this comment, i started to develop multi-tenant application, and found nothing but disappointment. You can't actually access request_context before open_session interface call. This means, you can't configure which database to use before opening a session.

My proposition.

Move open_session call to full_dispatch_request, and add interfaces and methods, similar to before_request - before_open_session, or call before_request before opening session (may break code that depends on session interface)