diff --git a/flask/app.py b/flask/app.py index 91139773..f75dd818 100644 --- a/flask/app.py +++ b/flask/app.py @@ -833,6 +833,7 @@ class Flask(_PackageBoundObject): self.debug = bool(debug) options.setdefault('use_reloader', self.debug) options.setdefault('use_debugger', self.debug) + options.setdefault('passthrough_errors', True) try: run_simple(host, port, self, **options) finally: diff --git a/flask/cli.py b/flask/cli.py index 360ce12e..141c9eea 100644 --- a/flask/cli.py +++ b/flask/cli.py @@ -422,7 +422,8 @@ def run_command(info, host, port, reload, debugger, eager_loading, print(' * Forcing debug %s' % (info.debug and 'on' or 'off')) run_simple(host, port, app, use_reloader=reload, - use_debugger=debugger, threaded=with_threads) + use_debugger=debugger, threaded=with_threads, + passthrough_errors=True) @click.command('shell', short_help='Runs a shell in the app context.') diff --git a/tests/test_basic.py b/tests/test_basic.py index d22e9e5b..d7cc7a3f 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -1222,6 +1222,26 @@ def test_exception_propagation(): t.join() +@pytest.mark.parametrize('debug', [True, False]) +@pytest.mark.parametrize('use_debugger', [True, False]) +@pytest.mark.parametrize('use_reloader', [True, False]) +@pytest.mark.parametrize('propagate_exceptions', [None, True, False]) +def test_werkzeug_passthrough_errors(monkeypatch, debug, use_debugger, + use_reloader, propagate_exceptions): + rv = {} + + # Mocks werkzeug.serving.run_simple method + def run_simple_mock(*args, **kwargs): + rv['passthrough_errors'] = kwargs.get('passthrough_errors') + + app = flask.Flask(__name__) + monkeypatch.setattr(werkzeug.serving, 'run_simple', run_simple_mock) + app.config['PROPAGATE_EXCEPTIONS'] = propagate_exceptions + app.run(debug=debug, use_debugger=use_debugger, use_reloader=use_reloader) + # make sure werkzeug always passes errors through + assert rv['passthrough_errors'] + + def test_max_content_length(): app = flask.Flask(__name__) app.config['MAX_CONTENT_LENGTH'] = 64