mirror of
https://github.com/jazzband/django-configurations.git
synced 2026-03-16 22:20:27 +00:00
implement error accumulation
This way, multiple ConfigurationErrors are caught during setup, accumulated and printed all at once
This commit is contained in:
parent
7de2615441
commit
a3b720f31a
3 changed files with 39 additions and 9 deletions
|
|
@ -4,6 +4,7 @@ import re
|
|||
from django.conf import global_settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
from .errors import ConfigurationError, SetupError
|
||||
from .utils import uppercase_attributes
|
||||
from .values import Value, setup_value
|
||||
|
||||
|
|
@ -142,6 +143,13 @@ class Configuration(metaclass=ConfigurationBase):
|
|||
|
||||
@classmethod
|
||||
def setup(cls):
|
||||
exceptions = []
|
||||
for name, value in uppercase_attributes(cls).items():
|
||||
if isinstance(value, Value):
|
||||
setup_value(cls, name, value)
|
||||
try:
|
||||
setup_value(cls, name, value)
|
||||
except ConfigurationError as err:
|
||||
exceptions.append(err)
|
||||
|
||||
if len(exceptions) > 0:
|
||||
raise SetupError(f"Couldn't setup values of configuration {cls.__name__}", exceptions)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,20 @@ class TermStyles:
|
|||
END = "\033[0m" if os.isatty(sys.stderr.fileno()) else ""
|
||||
|
||||
|
||||
class SetupError(Exception):
|
||||
"""
|
||||
Exception that gets raised when a configuration class cannot be set up by the importer
|
||||
"""
|
||||
def __init__(self, msg: str, child_errors: List['ConfigurationError'] = None) -> None:
|
||||
"""
|
||||
:param step_verb: Which step the importer tried to perform (e.g. import, setup)
|
||||
:param configuration_path: The full module path of the configuration that was supposed to be set up
|
||||
:param child_errors: Optional child configuration errors that caused this error
|
||||
"""
|
||||
super().__init__(msg)
|
||||
self.child_errors = child_errors or []
|
||||
|
||||
|
||||
class ConfigurationError(ValueError):
|
||||
"""
|
||||
Base error class that is used to indicate that something went wrong during configuration.
|
||||
|
|
@ -95,10 +109,13 @@ def with_error_handler(callee: Callable) -> Callable:
|
|||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
return callee(*args, **kwargs)
|
||||
except ConfigurationError as e:
|
||||
msg = "{}{}{}".format(TermStyles.RED + TermStyles.BOLD, e, TermStyles.END)
|
||||
for line in e.explanation_lines:
|
||||
msg += f"\n {line}"
|
||||
except SetupError as e:
|
||||
msg = f"{str(e)}"
|
||||
for child_error in e.child_errors:
|
||||
msg += f"\n * {child_error.main_error_msg}"
|
||||
for explanation_line in child_error.explanation_lines:
|
||||
msg += f"\n - {explanation_line}"
|
||||
|
||||
print(msg, file=sys.stderr)
|
||||
|
||||
return wrapper
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ from django.conf import ENVIRONMENT_VARIABLE as SETTINGS_ENVIRONMENT_VARIABLE
|
|||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.core.management import base
|
||||
|
||||
from .errors import SetupError, ConfigurationError
|
||||
from .utils import uppercase_attributes, reraise
|
||||
from .values import Value, setup_value
|
||||
|
||||
|
|
@ -149,10 +150,10 @@ class ConfigurationLoader:
|
|||
|
||||
try:
|
||||
cls = getattr(mod, self.name)
|
||||
except AttributeError as err: # pragma: no cover
|
||||
reraise(err, "Couldn't find configuration '{0}' "
|
||||
"in module '{1}'".format(self.name,
|
||||
mod.__package__))
|
||||
except AttributeError: # pragma: no cover
|
||||
raise SetupError(f"Couldn't find configuration '{self.name}' in module {mod.__package__}.\n"
|
||||
f"Hint: '{self.name}' is taken from the environment variable '{CONFIGURATION_ENVIRONMENT_VARIABLE}'"
|
||||
f"and '{mod.__package__}' from the environment variable '{SETTINGS_ENVIRONMENT_VARIABLE}'.")
|
||||
try:
|
||||
cls.pre_setup()
|
||||
cls.setup()
|
||||
|
|
@ -172,6 +173,10 @@ class ConfigurationLoader:
|
|||
self.name))
|
||||
cls.post_setup()
|
||||
|
||||
except SetupError:
|
||||
raise
|
||||
except ConfigurationError as err:
|
||||
raise SetupError(f"Couldn't setup configuration '{cls_path}'", [err])
|
||||
except Exception as err:
|
||||
reraise(err, "Couldn't setup configuration '{0}'".format(cls_path))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue