Skip to content
This repository
Browse code

Added a PROPAGATE_EXCEPTIONS flag

  • Loading branch information...
commit 8569dfee6136bfda4a5fa2297aed3d82700bb1a5 1 parent ed517c7
Armin Ronacher authored November 29, 2010
4  CHANGES
@@ -23,6 +23,10 @@ Release date to be announced, codename to be selected
23 23
   1.0 the old behaviour will continue to work but issue dependency
24 24
   warnings.
25 25
 - fixed a problem for Flask to run on jython.
  26
+- added a `PROPAGATE_EXCEPTIONS` configuration variable that can be
  27
+  used to flip the setting of exception propagation which previously
  28
+  was linked to `DEBUG` alone and is now linked to either `DEBUG` or
  29
+  `TESTING`.
26 30
 
27 31
 Version 0.6.1
28 32
 -------------
8  docs/config.rst
Source Rendered
@@ -54,6 +54,11 @@ The following configuration values are used internally by Flask:
54 54
 =============================== =========================================
55 55
 ``DEBUG``                       enable/disable debug mode
56 56
 ``TESTING``                     enable/disable testing mode
  57
+``PROPAGATE_EXCEPTIONS``        explicitly enable or disable the
  58
+                                propagation of exceptions.  If not set or
  59
+                                explicitly set to `None` this is
  60
+                                implicitly true if either `TESTING` or
  61
+                                `DEBUG` is true.
57 62
 ``SECRET_KEY``                  the secret key
58 63
 ``SESSION_COOKIE_NAME``         the name of the session cookie
59 64
 ``PERMANENT_SESSION_LIFETIME``  the lifetime of a permanent session as
@@ -96,6 +101,9 @@ The following configuration values are used internally by Flask:
96 101
 .. versionadded:: 0.6
97 102
    ``MAX_CONTENT_LENGTH``
98 103
 
  104
+.. versionadded:: 0.7
  105
+   ``PROPAGATE_EXCEPTIONS``
  106
+
99 107
 Configuring from Files
100 108
 ----------------------
101 109
 
15  flask/app.py
@@ -189,6 +189,7 @@ class Flask(_PackageBoundObject):
189 189
     default_config = ImmutableDict({
190 190
         'DEBUG':                                False,
191 191
         'TESTING':                              False,
  192
+        'PROPAGATE_EXCEPTIONS':                 None,
192 193
         'SECRET_KEY':                           None,
193 194
         'SESSION_COOKIE_NAME':                  'session',
194 195
         'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),
@@ -304,6 +305,18 @@ def __init__(self, import_name, static_path=None):
304 305
         self.init_jinja_globals()
305 306
 
306 307
     @property
  308
+    def propagate_exceptions(self):
  309
+        """Returns the value of the `PROPAGATE_EXCEPTIONS` configuration
  310
+        value in case it's set, otherwise a sensible default is returned.
  311
+
  312
+        .. versionadded:: 0.7
  313
+        """
  314
+        rv = self.config['PROPAGATE_EXCEPTIONS']
  315
+        if rv is not None:
  316
+            return rv
  317
+        return self.testing or self.debug
  318
+
  319
+    @property
307 320
     def logger(self):
308 321
         """A :class:`logging.Logger` object for this application.  The
309 322
         default configuration is to log to stderr if the application is
@@ -682,7 +695,7 @@ def handle_exception(self, e):
682 695
         """
683 696
         got_request_exception.send(self, exception=e)
684 697
         handler = self.error_handlers.get(500)
685  
-        if self.debug:
  698
+        if self.propagate_exceptions:
686 699
             raise
687 700
         self.logger.exception('Exception on %s [%s]' % (
688 701
             request.path,
29  tests/flask_tests.py
@@ -15,6 +15,7 @@
15 15
 import sys
16 16
 import flask
17 17
 import unittest
  18
+from threading import Thread
18 19
 from logging import StreamHandler
19 20
 from contextlib import contextmanager
20 21
 from datetime import datetime
@@ -547,7 +548,6 @@ def sub():
547 548
                 "No ValueError exception should have been raised \"%s\"" % e
548 549
             )
549 550
 
550  
-
551 551
     def test_test_app_proper_environ(self):
552 552
         app = flask.Flask(__name__)
553 553
         app.config.update(
@@ -619,6 +619,33 @@ def subdomain():
619 619
                 "No ValueError exception should have been raised \"%s\"" % e
620 620
             )
621 621
 
  622
+    def test_exception_propagation(self):
  623
+        def apprunner(configkey):
  624
+            app = flask.Flask(__name__)
  625
+            @app.route('/')
  626
+            def index():
  627
+                1/0
  628
+            c = app.test_client()
  629
+            if config_key is not None:
  630
+                app.config[config_key] = True
  631
+                try:
  632
+                    resp = c.get('/')
  633
+                except Exception:
  634
+                    pass
  635
+                else:
  636
+                    self.fail('expected exception')
  637
+            else:
  638
+                assert c.get('/').status_code == 500
  639
+
  640
+        # we have to run this test in an isolated thread because if the
  641
+        # debug flag is set to true and an exception happens the context is
  642
+        # not torn down.  This causes other tests that run after this fail
  643
+        # when they expect no exception on the stack.
  644
+        for config_key in 'TESTING', 'PROPAGATE_EXCEPTIONS', 'DEBUG', None:
  645
+            t = Thread(target=apprunner, args=(config_key,))
  646
+            t.start()
  647
+            t.join()
  648
+
622 649
 
623 650
 class JSONTestCase(unittest.TestCase):
624 651
 

0 notes on commit 8569dfe

Please sign in to comment.
Something went wrong with that request. Please try again.