Added a PROPAGATE_EXCEPTIONS flag
This commit is contained in:
parent
ed517c7215
commit
8569dfee61
4 changed files with 54 additions and 2 deletions
4
CHANGES
4
CHANGES
|
|
@ -23,6 +23,10 @@ Release date to be announced, codename to be selected
|
||||||
1.0 the old behaviour will continue to work but issue dependency
|
1.0 the old behaviour will continue to work but issue dependency
|
||||||
warnings.
|
warnings.
|
||||||
- fixed a problem for Flask to run on jython.
|
- fixed a problem for Flask to run on jython.
|
||||||
|
- added a `PROPAGATE_EXCEPTIONS` configuration variable that can be
|
||||||
|
used to flip the setting of exception propagation which previously
|
||||||
|
was linked to `DEBUG` alone and is now linked to either `DEBUG` or
|
||||||
|
`TESTING`.
|
||||||
|
|
||||||
Version 0.6.1
|
Version 0.6.1
|
||||||
-------------
|
-------------
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,11 @@ The following configuration values are used internally by Flask:
|
||||||
=============================== =========================================
|
=============================== =========================================
|
||||||
``DEBUG`` enable/disable debug mode
|
``DEBUG`` enable/disable debug mode
|
||||||
``TESTING`` enable/disable testing mode
|
``TESTING`` enable/disable testing mode
|
||||||
|
``PROPAGATE_EXCEPTIONS`` explicitly enable or disable the
|
||||||
|
propagation of exceptions. If not set or
|
||||||
|
explicitly set to `None` this is
|
||||||
|
implicitly true if either `TESTING` or
|
||||||
|
`DEBUG` is true.
|
||||||
``SECRET_KEY`` the secret key
|
``SECRET_KEY`` the secret key
|
||||||
``SESSION_COOKIE_NAME`` the name of the session cookie
|
``SESSION_COOKIE_NAME`` the name of the session cookie
|
||||||
``PERMANENT_SESSION_LIFETIME`` the lifetime of a permanent session as
|
``PERMANENT_SESSION_LIFETIME`` the lifetime of a permanent session as
|
||||||
|
|
@ -96,6 +101,9 @@ The following configuration values are used internally by Flask:
|
||||||
.. versionadded:: 0.6
|
.. versionadded:: 0.6
|
||||||
``MAX_CONTENT_LENGTH``
|
``MAX_CONTENT_LENGTH``
|
||||||
|
|
||||||
|
.. versionadded:: 0.7
|
||||||
|
``PROPAGATE_EXCEPTIONS``
|
||||||
|
|
||||||
Configuring from Files
|
Configuring from Files
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
|
|
||||||
15
flask/app.py
15
flask/app.py
|
|
@ -189,6 +189,7 @@ class Flask(_PackageBoundObject):
|
||||||
default_config = ImmutableDict({
|
default_config = ImmutableDict({
|
||||||
'DEBUG': False,
|
'DEBUG': False,
|
||||||
'TESTING': False,
|
'TESTING': False,
|
||||||
|
'PROPAGATE_EXCEPTIONS': None,
|
||||||
'SECRET_KEY': None,
|
'SECRET_KEY': None,
|
||||||
'SESSION_COOKIE_NAME': 'session',
|
'SESSION_COOKIE_NAME': 'session',
|
||||||
'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
|
'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
|
||||||
|
|
@ -303,6 +304,18 @@ class Flask(_PackageBoundObject):
|
||||||
self.jinja_env = self.create_jinja_environment()
|
self.jinja_env = self.create_jinja_environment()
|
||||||
self.init_jinja_globals()
|
self.init_jinja_globals()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def propagate_exceptions(self):
|
||||||
|
"""Returns the value of the `PROPAGATE_EXCEPTIONS` configuration
|
||||||
|
value in case it's set, otherwise a sensible default is returned.
|
||||||
|
|
||||||
|
.. versionadded:: 0.7
|
||||||
|
"""
|
||||||
|
rv = self.config['PROPAGATE_EXCEPTIONS']
|
||||||
|
if rv is not None:
|
||||||
|
return rv
|
||||||
|
return self.testing or self.debug
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def logger(self):
|
def logger(self):
|
||||||
"""A :class:`logging.Logger` object for this application. The
|
"""A :class:`logging.Logger` object for this application. The
|
||||||
|
|
@ -682,7 +695,7 @@ class Flask(_PackageBoundObject):
|
||||||
"""
|
"""
|
||||||
got_request_exception.send(self, exception=e)
|
got_request_exception.send(self, exception=e)
|
||||||
handler = self.error_handlers.get(500)
|
handler = self.error_handlers.get(500)
|
||||||
if self.debug:
|
if self.propagate_exceptions:
|
||||||
raise
|
raise
|
||||||
self.logger.exception('Exception on %s [%s]' % (
|
self.logger.exception('Exception on %s [%s]' % (
|
||||||
request.path,
|
request.path,
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import re
|
||||||
import sys
|
import sys
|
||||||
import flask
|
import flask
|
||||||
import unittest
|
import unittest
|
||||||
|
from threading import Thread
|
||||||
from logging import StreamHandler
|
from logging import StreamHandler
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
@ -547,7 +548,6 @@ class BasicFunctionalityTestCase(unittest.TestCase):
|
||||||
"No ValueError exception should have been raised \"%s\"" % e
|
"No ValueError exception should have been raised \"%s\"" % e
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_test_app_proper_environ(self):
|
def test_test_app_proper_environ(self):
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
app.config.update(
|
app.config.update(
|
||||||
|
|
@ -619,6 +619,33 @@ class BasicFunctionalityTestCase(unittest.TestCase):
|
||||||
"No ValueError exception should have been raised \"%s\"" % e
|
"No ValueError exception should have been raised \"%s\"" % e
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_exception_propagation(self):
|
||||||
|
def apprunner(configkey):
|
||||||
|
app = flask.Flask(__name__)
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
1/0
|
||||||
|
c = app.test_client()
|
||||||
|
if config_key is not None:
|
||||||
|
app.config[config_key] = True
|
||||||
|
try:
|
||||||
|
resp = c.get('/')
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.fail('expected exception')
|
||||||
|
else:
|
||||||
|
assert c.get('/').status_code == 500
|
||||||
|
|
||||||
|
# we have to run this test in an isolated thread because if the
|
||||||
|
# debug flag is set to true and an exception happens the context is
|
||||||
|
# not torn down. This causes other tests that run after this fail
|
||||||
|
# when they expect no exception on the stack.
|
||||||
|
for config_key in 'TESTING', 'PROPAGATE_EXCEPTIONS', 'DEBUG', None:
|
||||||
|
t = Thread(target=apprunner, args=(config_key,))
|
||||||
|
t.start()
|
||||||
|
t.join()
|
||||||
|
|
||||||
|
|
||||||
class JSONTestCase(unittest.TestCase):
|
class JSONTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue