pallets / flask

The Python micro framework for building web applications.
https://flask.palletsprojects.com
BSD 3-Clause "New" or "Revised" License
68.07k stars 16.22k forks source link

Better exception handling when env vars are missing for flask CLI #2741

Closed rochacbruno closed 4 years ago

rochacbruno commented 6 years ago

Expected Behavior

As there is the support for lazy loading the app, when running flask CLI without providing the proper environment variables we must see a better warning instead of raw exception.

Tell us what should happen.

we should see a better warning or message pointing to the problem

# there is no FLASK_APP env var
$ flask --help
WARNING: You need to define the app e.g: `export FLASK_APP=app.py`

Actual Behavior

Tell us what happens instead.

we see traceback before the help message

# there is no FLASK_APP env var
$ flask --help                                                               Sat 28 Apr 2018 01:25:50 PM -03
Traceback (most recent call last):
  File "~Projects/personal/flasgger/venv/lib/python3.6/site-packages/flask/cli.py", line 235, in locate_app
    __import__(module_name)
ModuleNotFoundError: No module named 'app'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "~/Projects/personal/flasgger/venv/lib/python3.6/site-packages/flask/cli.py", line 529, in list_commands
    rv.update(info.load_app().cli.list_commands(ctx))
  File "~/Projects/personal/flasgger/venv/lib/python3.6/site-packages/flask/cli.py", line 372, in load_app
    app = locate_app(self, import_name, name)
  File "~/Projects/personal/flasgger/venv/lib/python3.6/site-packages/flask/cli.py", line 246, in locate_app
    'Could not import "{name}".'.format(name=module_name)
flask.cli.NoAppException: Could not import "app".
Usage: flask [OPTIONS] COMMAND [ARGS]...

  A general utility script for Flask applications.

  Provides commands from Flask, extensions, and the application. Loads the
  application defined in the FLASK_APP environment variable, or from a
  wsgi.py file. Setting the FLASK_ENV environment variable to 'development'
  will enable debug mode.

    $ export FLASK_APP=hello.py
    $ export FLASK_ENV=development
    $ flask run

Options:
  --version  Show the flask version
  --help     Show this message and exit.

Commands:
  routes  Show the routes for the app.
  run     Runs a development server.
  shell   Runs a shell in the app context.

The same happens to run

$ flask run                                                          429ms  Sat 28 Apr 2018 01:32:48 PM -03
 * Serving Flask app "app.py"
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
Usage: flask run [OPTIONS]

Error: Could not import "app".

The Error: Could not import "app". could include WARNING: You need to define the app e.g: export FLASK_APP=app.py

Suggestion

We could check the existence of FLASK_APP envvar before running any of the commands in the Group Cli, if FLASK_APP does not exist the dispatch of commands never happens.

Environment

rochacbruno commented 6 years ago
davidism commented 6 years ago

Anything that improves help messages is great.

nerixim commented 5 years ago

Looks better in flask 1.0.2, so maybe we can close this?

~/flask flask --help
Traceback (most recent call last):
  File "/Users/username/.local/share/virtualenvs/flask-C1e3YqV7/lib/python3.7/site-packages/flask/cli.py", line 529, in list_commands
    rv.update(info.load_app().cli.list_commands(ctx))
  File "/Users/username/.local/share/virtualenvs/flask-C1e3YqV7/lib/python3.7/site-packages/flask/cli.py", line 384, in load_app
    'Could not locate a Flask application. You did not provide '
flask.cli.NoAppException: Could not locate a Flask application. You did not provide the "FLASK_APP" environment variable, and a "wsgi.py" or "app.py" module was not found in the current directory.
Usage: flask [OPTIONS] COMMAND [ARGS]...

  A general utility script for Flask applications.

  Provides commands from Flask, extensions, and the application. Loads the
  application defined in the FLASK_APP environment variable, or from a
  wsgi.py file. Setting the FLASK_ENV environment variable to 'development'
  will enable debug mode.

    $ export FLASK_APP=hello.py
    $ export FLASK_ENV=development
    $ flask run

Options:
  --version  Show the flask version
  --help     Show this message and exit.

Commands:
  routes  Show the routes for the app.
  run     Runs a development server.
  shell   Runs a shell in the app context.
 ~/flask flask run   
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
Usage: flask run [OPTIONS]

Error: Could not locate a Flask application. You did not provide the "FLASK_APP" environment variable, and a "wsgi.py" or "app.py" module was not found in the current directory.
ThiefMaster commented 4 years ago

Please keep discussions in English, we can't support other languages.

davidism commented 4 years ago

The various exception messages, including when the env var wasn't set and a default wasn't found, have improved over time. That one now reads:

Could not locate a Flask application. You did not provide the "FLASK_APP" environment variable, and a "wsgi.py" or "app.py" module was not found in the current directory.

Tracebacks were added in #2208 to avoid confusion caused by the previous behavior where list_commands() hid errors completely.

After reviewing the code, I think we should show only the error message for NoAppException, while still showing the full traceback for other exceptions. Tracebacks for loading errors are no longer helpful as they only show Flask internals. We still want to show the help text because the flask --help command still has useful output.