Skip to content

Commit 2cacb7b

Browse files
author
David Martin
committed
refactor - use ValitationError exception subclass to handle & format list of errors in message
Signed-off-by: David Martin <[email protected]>
1 parent d20c3ca commit 2cacb7b

File tree

3 files changed

+43
-16
lines changed

3 files changed

+43
-16
lines changed

chaoslib/exceptions.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
__all__ = ["ChaosException", "InvalidExperiment", "InvalidActivity",
44
"ActivityFailed", "DiscoveryFailed", "InvalidSource",
55
"InterruptExecution", "ControlPythonFunctionLoadingError",
6-
"InvalidControl"]
6+
"InvalidControl", "ValidationError"]
77

88

99
class ChaosException(Exception):
@@ -44,3 +44,30 @@ class InterruptExecution(ChaosException):
4444

4545
class InvalidControl(ChaosException):
4646
pass
47+
48+
49+
class ValidationError(ChaosException):
50+
def __init__(self, msg, errors, *args, **kwargs):
51+
"""
52+
:param msg: exception message
53+
:param errors: single error as string or list of errors/exceptions
54+
"""
55+
if isinstance(errors, str):
56+
errors = [errors]
57+
self.errors = errors
58+
super().__init__(msg, *args, **kwargs)
59+
60+
def __str__(self) -> str:
61+
errors = self.errors
62+
nb_errors = len(errors)
63+
err_msg = super().__str__()
64+
return (
65+
"{msg}{dot} {nb} validation error{plural}:\n"
66+
" - {errors}".format(
67+
msg=err_msg,
68+
dot="" if err_msg.endswith(".") else ".",
69+
nb=nb_errors,
70+
plural="" if nb_errors == 1 else "s",
71+
errors="\n - ".join([str(err) for err in errors])
72+
)
73+
)

chaoslib/experiment.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
cleanup_global_controls
1616
from chaoslib.deprecation import warn_about_deprecated_features
1717
from chaoslib.exceptions import ActivityFailed, ChaosException, \
18-
InterruptExecution, InvalidActivity, InvalidExperiment
18+
InterruptExecution, InvalidActivity, InvalidExperiment, ValidationError
1919
from chaoslib.extension import validate_extensions
2020
from chaoslib.configuration import load_configuration
2121
from chaoslib.hypothesis import ensure_hypothesis_is_valid, \
@@ -55,10 +55,14 @@ def ensure_experiment_is_valid(experiment: Experiment):
5555
"""
5656
logger.info("Validating the experiment's syntax")
5757

58+
full_validation_msg = 'Experiment is not valid, ' \
59+
'please fix the following errors'
5860
errors = []
5961

6062
if not experiment:
61-
raise InvalidExperiment("an empty experiment is not an experiment")
63+
# empty experiment, cannot continue validation any further
64+
raise ValidationError(full_validation_msg,
65+
"an empty experiment is not an experiment")
6266

6367
if not experiment.get("title"):
6468
errors.append(InvalidExperiment("experiment requires a title"))
@@ -103,11 +107,7 @@ def ensure_experiment_is_valid(experiment: Experiment):
103107
errors.extend(validate_controls(experiment))
104108

105109
if errors:
106-
full_validation_msg = 'Experiment is not valid, ' \
107-
'please fix the following errors:'
108-
for error in errors:
109-
full_validation_msg += '\n- {}'.format(error)
110-
raise InvalidExperiment(full_validation_msg)
110+
raise ValidationError(full_validation_msg, errors)
111111

112112
logger.info("Experiment looks valid")
113113

tests/test_experiment.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import yaml
1313

1414
from chaoslib.exceptions import ActivityFailed, InvalidActivity, \
15-
InvalidExperiment, InterruptExecution
15+
InvalidExperiment, InterruptExecution, ValidationError
1616
from chaoslib.experiment import ensure_experiment_is_valid, load_experiment, \
1717
run_experiment, run_activities
1818
from chaoslib.types import Experiment
@@ -21,7 +21,7 @@
2121

2222

2323
def test_empty_experiment_is_invalid():
24-
with pytest.raises(InvalidExperiment) as exc:
24+
with pytest.raises(ValidationError) as exc:
2525
ensure_experiment_is_valid(experiments.EmptyExperiment)
2626
assert "an empty experiment is not an experiment" in str(exc.value)
2727

@@ -65,27 +65,27 @@ def test_unknown_extension():
6565

6666

6767
def test_experiment_must_have_a_method():
68-
with pytest.raises(InvalidExperiment) as exc:
68+
with pytest.raises(ValidationError) as exc:
6969
ensure_experiment_is_valid(experiments.MissingMethodExperiment)
7070
assert "an experiment requires a method with "\
7171
"at least one activity" in str(exc.value)
7272

7373

7474
def test_experiment_must_have_at_least_one_step():
75-
with pytest.raises(InvalidExperiment) as exc:
75+
with pytest.raises(ValidationError) as exc:
7676
ensure_experiment_is_valid(experiments.NoStepsMethodExperiment)
7777
assert "an experiment requires a method with "\
7878
"at least one activity" in str(exc.value)
7979

8080

8181
def test_experiment_must_have_a_title():
82-
with pytest.raises(InvalidExperiment) as exc:
82+
with pytest.raises(ValidationError) as exc:
8383
ensure_experiment_is_valid(experiments.MissingTitleExperiment)
8484
assert "experiment requires a title" in str(exc.value)
8585

8686

8787
def test_experiment_must_have_a_description():
88-
with pytest.raises(InvalidExperiment) as exc:
88+
with pytest.raises(ValidationError) as exc:
8989
ensure_experiment_is_valid(experiments.MissingDescriptionExperiment)
9090
assert "experiment requires a description" in str(exc.value)
9191

@@ -96,13 +96,13 @@ def test_experiment_may_not_have_a_hypothesis():
9696

9797

9898
def test_experiment_hypothesis_must_have_a_title():
99-
with pytest.raises(InvalidExperiment) as exc:
99+
with pytest.raises(ValidationError) as exc:
100100
ensure_experiment_is_valid(experiments.MissingHypothesisTitleExperiment)
101101
assert "hypothesis requires a title" in str(exc.value)
102102

103103

104104
def test_experiment_hypothesis_must_have_a_valid_probe():
105-
with pytest.raises(InvalidExperiment) as exc:
105+
with pytest.raises(ValidationError) as exc:
106106
ensure_experiment_is_valid(experiments.ExperimentWithInvalidHypoProbe)
107107
assert "required argument 'path' is missing from activity" in str(exc.value)
108108

0 commit comments

Comments
 (0)