Browse Source

Improved bad factory error handling

pull/2530/head
Armin Ronacher 7 years ago
parent
commit
c23a63a185
  1. 10
      flask/cli.py
  2. 7
      tests/test_cli.py

10
flask/cli.py

@ -33,6 +33,12 @@ except ImportError:
dotenv = None dotenv = None
def _called_with_wrong_args(factory, exc_info):
exc_type, exc_value, tb = exc_info
return exc_type is TypeError and \
str(exc_value).startswith('%s() takes' % factory.__name__)
class NoAppException(click.UsageError): class NoAppException(click.UsageError):
"""Raised if an application cannot be found or loaded.""" """Raised if an application cannot be found or loaded."""
@ -75,6 +81,8 @@ def find_best_app(script_info, module):
if isinstance(app, Flask): if isinstance(app, Flask):
return app return app
except TypeError: except TypeError:
if not _called_with_wrong_args(app_factory, sys.exc_info()):
raise
raise NoAppException( raise NoAppException(
'Detected factory "{factory}" in module "{module}", but ' 'Detected factory "{factory}" in module "{module}", but '
'could not call it without arguments. Use ' 'could not call it without arguments. Use '
@ -148,6 +156,8 @@ def find_app_by_string(script_info, module, app_name):
try: try:
app = call_factory(script_info, attr, args) app = call_factory(script_info, attr, args)
except TypeError as e: except TypeError as e:
if not _called_with_wrong_args(attr, sys.exc_info()):
raise
raise NoAppException( raise NoAppException(
'{e}\nThe factory "{app_name}" in module "{module}" could not ' '{e}\nThe factory "{app_name}" in module "{module}" could not '
'be called with the specified arguments.'.format( 'be called with the specified arguments.'.format(

7
tests/test_cli.py

@ -144,6 +144,13 @@ def test_find_best_app(test_apps):
pytest.raises(NoAppException, find_best_app, script_info, Module) pytest.raises(NoAppException, find_best_app, script_info, Module)
class Module:
@staticmethod
def create_app():
raise TypeError('bad bad factory!')
pytest.raises(TypeError, find_best_app, script_info, Module)
@pytest.mark.parametrize('value,path,result', ( @pytest.mark.parametrize('value,path,result', (
('test', cwd, 'test'), ('test', cwd, 'test'),

Loading…
Cancel
Save