From b05604005362f00b8595e2cda763f1467124585e Mon Sep 17 00:00:00 2001 From: David Martin Date: Wed, 18 Dec 2019 14:23:52 +0100 Subject: [PATCH] refactor - use ValitationError exception subclass to handle & format list of errors in message Signed-off-by: David Martin --- chaoslib/exceptions.py | 29 ++++++++++++++++++++++++++++- chaoslib/experiment.py | 14 +++++++------- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/chaoslib/exceptions.py b/chaoslib/exceptions.py index ef4476f..3697c73 100644 --- a/chaoslib/exceptions.py +++ b/chaoslib/exceptions.py @@ -3,7 +3,7 @@ __all__ = ["ChaosException", "InvalidExperiment", "InvalidActivity", "ActivityFailed", "DiscoveryFailed", "InvalidSource", "InterruptExecution", "ControlPythonFunctionLoadingError", - "InvalidControl"] + "InvalidControl", "ValidationError"] class ChaosException(Exception): @@ -44,3 +44,30 @@ class InterruptExecution(ChaosException): class InvalidControl(ChaosException): pass + + +class ValidationError(ChaosException): + def __init__(self, msg, errors, *args, **kwargs): + """ + :param msg: exception message + :param errors: single error as string or list of errors/exceptions + """ + if isinstance(errors, str): + errors = [errors] + self.errors = errors + super().__init__(msg, *args, **kwargs) + + def __str__(self) -> str: + errors = self.errors + nb_errors = len(errors) + err_msg = super().__str__() + return ( + "{msg}{dot} {nb} validation error{plural}:\n" + " - {errors}".format( + msg=err_msg, + dot="" if err_msg.endswith(".") else ".", + nb=nb_errors, + plural="" if nb_errors == 1 else "s", + errors="\n - ".join([str(err) for err in errors]) + ) + ) diff --git a/chaoslib/experiment.py b/chaoslib/experiment.py index 1805eb0..154ad2f 100644 --- a/chaoslib/experiment.py +++ b/chaoslib/experiment.py @@ -15,7 +15,7 @@ cleanup_global_controls from chaoslib.deprecation import warn_about_deprecated_features from chaoslib.exceptions import ActivityFailed, ChaosException, \ - InterruptExecution, InvalidActivity, InvalidExperiment + InterruptExecution, InvalidActivity, InvalidExperiment, ValidationError from chaoslib.extension import validate_extensions from chaoslib.configuration import load_configuration from chaoslib.hypothesis import ensure_hypothesis_is_valid, \ @@ -55,10 +55,14 @@ def ensure_experiment_is_valid(experiment: Experiment): """ logger.info("Validating the experiment's syntax") + full_validation_msg = 'Experiment is not valid, ' \ + 'please fix the following errors' errors = [] if not experiment: - raise InvalidExperiment("an empty experiment is not an experiment") + # empty experiment, cannot continue validation any further + raise ValidationError(full_validation_msg, + "an empty experiment is not an experiment") if not experiment.get("title"): errors.append(InvalidExperiment("experiment requires a title")) @@ -103,11 +107,7 @@ def ensure_experiment_is_valid(experiment: Experiment): errors.extend(validate_controls(experiment)) if errors: - full_validation_msg = 'Experiment is not valid, ' \ - 'please fix the following errors:' - for error in errors: - full_validation_msg += '\n- {}'.format(error) - raise InvalidExperiment(full_validation_msg) + raise ValidationError(full_validation_msg, errors) logger.info("Experiment looks valid")