From aa6dd09c2cab5eb15a45d73b5ade24b7b4131c5a Mon Sep 17 00:00:00 2001 From: Rohan salwan Date: Wed, 23 Jun 2021 05:06:03 +0530 Subject: [PATCH] correctly handle raising deferred errors in cli lazy loading --- CHANGES.rst | 2 ++ src/flask/cli.py | 17 +++++++++-------- tests/test_cli.py | 5 +++++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 44512451..dc3f5cbf 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -17,6 +17,8 @@ Unreleased :issue:`4150` - ``jsonify`` handles ``decimal.Decimal`` by encoding to ``str``. :issue:`4157` +- Correctly handle raising deferred errors in CLI lazy loading. + :issue:`4096` Version 2.0.1 diff --git a/src/flask/cli.py b/src/flask/cli.py index d9e810da..81191a1a 100644 --- a/src/flask/cli.py +++ b/src/flask/cli.py @@ -312,7 +312,7 @@ class DispatchingApp: self.loader = loader self._app = None self._lock = Lock() - self._bg_loading_exc_info = None + self._bg_loading_exc = None if use_eager_loading is None: use_eager_loading = os.environ.get("WERKZEUG_RUN_MAIN") != "true" @@ -328,23 +328,24 @@ class DispatchingApp: with self._lock: try: self._load_unlocked() - except Exception: - self._bg_loading_exc_info = sys.exc_info() + except Exception as e: + self._bg_loading_exc = e t = Thread(target=_load_app, args=()) t.start() def _flush_bg_loading_exception(self): __traceback_hide__ = True # noqa: F841 - exc_info = self._bg_loading_exc_info - if exc_info is not None: - self._bg_loading_exc_info = None - raise exc_info + exc = self._bg_loading_exc + + if exc is not None: + self._bg_loading_exc = None + raise exc def _load_unlocked(self): __traceback_hide__ = True # noqa: F841 self._app = rv = self.loader() - self._bg_loading_exc_info = None + self._bg_loading_exc = None return rv def __call__(self, environ, start_response): diff --git a/tests/test_cli.py b/tests/test_cli.py index ebf8d1f5..2edb0bdd 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -17,6 +17,7 @@ from flask import Blueprint from flask import current_app from flask import Flask from flask.cli import AppGroup +from flask.cli import DispatchingApp from flask.cli import dotenv from flask.cli import find_best_app from flask.cli import FlaskGroup @@ -659,3 +660,7 @@ def test_click_7_deprecated(): pytest.deprecated_call(cli_main, match=".* Click 7 is deprecated") else: cli_main() + + +def test_load_in_background(): + pytest.raises(Exception, DispatchingApp, "appname123")