jazzband / django-configurations

A helper for organizing Django project settings by relying on well established programming patterns.

Home Page:https://django-configurations.readthedocs.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

An error in a validator can cause a stacktrace that is extremely hard to diagnose

LucidDan opened this issue · comments

When a validation error occurs in a large and complex configuration, it can be almost impossible to figure out what the actual error was.
Take a case here, where a URL is being set to an empty string...but what value is it? There's no mention of the line number or the setting name or the environ_name it is sourced from - see the stack trace output at the end of this issue description.

This could be improved significantly in a couple of ways:

  1. Clean up the stack trace so that the output is a clean error message reporting the validation and where it failed.
  2. Include the environ_name and/or setting attribute in the validation error message.

The output I got was as below:

(mywifitribe-DwskTOg3-py3.9) ➜  my_wifitribe_co git:(master) ✗ ./manage.py
Traceback (most recent call last):
  File "/Users/dans/Library/Caches/pypoetry/virtualenvs/mywifitribe-DwskTOg3-py3.9/lib/python3.9/site-packages/configurations/values.py", line 355, in to_python
    self._validator(value)
  File "/Users/dans/Library/Caches/pypoetry/virtualenvs/mywifitribe-DwskTOg3-py3.9/lib/python3.9/site-packages/django/core/validators.py", line 105, in __call__
    raise ValidationError(self.message, code=self.code)
django.core.exceptions.ValidationError: <exception str() failed>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/dans/PycharmProjects/my_wifitribe_co/./manage.py", line 33, in <module>
    main()
  File "/Users/dans/PycharmProjects/my_wifitribe_co/./manage.py", line 29, in main
    execute_from_command_line(sys.argv)
  File "/Users/dans/Library/Caches/pypoetry/virtualenvs/mywifitribe-DwskTOg3-py3.9/lib/python3.9/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "/Users/dans/Library/Caches/pypoetry/virtualenvs/mywifitribe-DwskTOg3-py3.9/lib/python3.9/site-packages/django/core/management/__init__.py", line 345, in execute
    settings.INSTALLED_APPS
  File "/Users/dans/Library/Caches/pypoetry/virtualenvs/mywifitribe-DwskTOg3-py3.9/lib/python3.9/site-packages/django/conf/__init__.py", line 83, in __getattr__
    self._setup(name)
  File "/Users/dans/Library/Caches/pypoetry/virtualenvs/mywifitribe-DwskTOg3-py3.9/lib/python3.9/site-packages/django/conf/__init__.py", line 70, in _setup
    self._wrapped = Settings(settings_module)
  File "/Users/dans/Library/Caches/pypoetry/virtualenvs/mywifitribe-DwskTOg3-py3.9/lib/python3.9/site-packages/django/conf/__init__.py", line 177, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/local/Cellar/python@3.9/3.9.0_2/Frameworks/Python.framework/Versions/3.9/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 627, in _load_backward_compatible
  File "/Users/dans/Library/Caches/pypoetry/virtualenvs/mywifitribe-DwskTOg3-py3.9/lib/python3.9/site-packages/configurations/importer.py", line 182, in load_module
    reraise(err, "Couldn't setup configuration '{0}'".format(cls_path))
  File "/Users/dans/Library/Caches/pypoetry/virtualenvs/mywifitribe-DwskTOg3-py3.9/lib/python3.9/site-packages/configurations/importer.py", line 164, in load_module
    cls.setup()
  File "/Users/dans/PycharmProjects/my_wifitribe_co/wifitribe/mywifitribe/settings/allauth.py", line 47, in setup
    super().setup()
  File "/Users/dans/PycharmProjects/my_wifitribe_co/wifitribe/mywifitribe/settings/whitenoise.py", line 25, in setup
    super().setup()
  File "/Users/dans/Library/Caches/pypoetry/virtualenvs/mywifitribe-DwskTOg3-py3.9/lib/python3.9/site-packages/configurations/base.py", line 127, in setup
    setup_value(cls, name, value)
  File "/Users/dans/Library/Caches/pypoetry/virtualenvs/mywifitribe-DwskTOg3-py3.9/lib/python3.9/site-packages/configurations/values.py", line 15, in setup_value
    actual_value = value.setup(name)
  File "/Users/dans/Library/Caches/pypoetry/virtualenvs/mywifitribe-DwskTOg3-py3.9/lib/python3.9/site-packages/configurations/values.py", line 103, in setup
    value = self.to_python(os.environ[full_environ_name])
  File "/Users/dans/Library/Caches/pypoetry/virtualenvs/mywifitribe-DwskTOg3-py3.9/lib/python3.9/site-packages/configurations/values.py", line 357, in to_python
    raise ValueError(self.message.format(value))
ValueError: Couldn't setup configuration 'wifitribe.mywifitribe.settings.DevConfig':  Cannot interpret URL value '' 

What I would've liked to see would be more like:

(mywifitribe-DwskTOg3-py3.9) ➜  my_wifitribe_co git:(master) ✗ ./manage.py
django-configurations: Couldn't set up configuration 'wifitribe.mywifitribe.settings.DevConfig':  got a validation error for setting DRAMATIQ_BROKER_URL: Cannot interpret URL value ''

As always, happy to do a PR along these lines, I don't think it would be too hard to do, but want to document the idea, and give people a chance to comment in the meantime.