diff --git a/doc/changes/unreleased.md b/doc/changes/unreleased.md index 8c23b3d..81d8510 100644 --- a/doc/changes/unreleased.md +++ b/doc/changes/unreleased.md @@ -4,3 +4,7 @@ * Relocked Dependencies * Update toolbox workflows + +## Added + +* Added support for finegrained error output control \ No newline at end of file diff --git a/exasol/error/_error.py b/exasol/error/_error.py index 456d24e..2176a99 100644 --- a/exasol/error/_error.py +++ b/exasol/error/_error.py @@ -52,8 +52,45 @@ def build_error(code, msg, mitigations, params): def __str__(self) -> str: return f"{self._error}" - # TODO: Implement __format__ to conveniently support long and short reporting format - # See also see, Github Issue #28 https://github.com/exasol/error-reporting-python/issues/28 + def __format__(self, format_spec: str): + def _name(error: Error): + return f"{error._error._error_code} " + + def _message(error: Error): + return f"{error._error._message_builder} " + + def _mitigations(error: Error): + return f"{error._error._mitigations} " + + def _parameters(error: Error): + return f"{error._error._parameter_dict} " + + def _short(error: Error): + return _name(error) + _message(error) + + def _long(error: Error): + return ( + _name(error) + + _message(error) + + _mitigations(error) + + _parameters(error) + ) + + output = "" + formats = { + "name": _name(self), + "message": _message(self), + "mitigations": _mitigations(self), + "parameters": _parameters(self), + "short": _short(self), + "long": _long(self), + "": "", + } + for part in format_spec.split(" "): + if part in formats: + output += formats[part] + + return output[:-1] # ATTENTION: In the event of an exception while creating an error, we encounter a chicken-and-egg problem regarding error definitions. diff --git a/poetry.lock b/poetry.lock index dc89afc..9c13650 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1690,13 +1690,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.28.1" +version = "20.29.0" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" files = [ - {file = "virtualenv-20.28.1-py3-none-any.whl", hash = "sha256:412773c85d4dab0409b83ec36f7a6499e72eaf08c80e81e9576bca61831c71cb"}, - {file = "virtualenv-20.28.1.tar.gz", hash = "sha256:5d34ab240fdb5d21549b76f9e8ff3af28252f5499fb6d6f031adac4e5a8c5329"}, + {file = "virtualenv-20.29.0-py3-none-any.whl", hash = "sha256:c12311863497992dc4b8644f8ea82d3b35bb7ef8ee82e6630d76d0197c39baf9"}, + {file = "virtualenv-20.29.0.tar.gz", hash = "sha256:6345e1ff19d4b1296954cee076baaf58ff2a12a84a338c62b02eda39f20aa982"}, ] [package.dependencies] diff --git a/test/unit/fmt_test.py b/test/unit/fmt_test.py new file mode 100644 index 0000000..9c8db87 --- /dev/null +++ b/test/unit/fmt_test.py @@ -0,0 +1,131 @@ +import pytest + +from exasol.error._error import Error + + +@pytest.mark.parametrize( + "error, fmt, expected", + [ + ( + Error( + code="E-TEST-1", + message="Not enough space on device {/dev/sda1}.", + mitigations=[ + "Delete something from {/dev/sda1}", + "Create larger partition.", + ], + parameters={"device": "/dev/sda1"}, + ), + "", + "", + ), + ( + Error( + code="E-TEST-1", + message="Not enough space on device {/dev/sda1}.", + mitigations=[ + "Delete something from {/dev/sda1}", + "Create larger partition.", + ], + parameters={"device": "/dev/sda1"}, + ), + "unknown", + "", + ), + ( + Error( + code="E-TEST-1", + message="Not enough space on device {/dev/sda1}.", + mitigations=[ + "Delete something from {/dev/sda1}", + "Create larger partition.", + ], + parameters={"device": "/dev/sda1"}, + ), + "long", + "E-TEST-1 ['Not enough space on device {/dev/sda1}.'] ['Delete something from {/dev/sda1}', 'Create larger partition.'] {'device': '/dev/sda1'}", + ), + ( + Error( + code="E-TEST-1", + message="Not enough space on device {/dev/sda1}.", + mitigations=[ + "Delete something from {/dev/sda1}", + "Create larger partition.", + ], + parameters={"device": "/dev/sda1"}, + ), + "short", + "E-TEST-1 ['Not enough space on device {/dev/sda1}.']", + ), + ( + Error( + code="E-TEST-1", + message="Not enough space on device {/dev/sda1}.", + mitigations=[ + "Delete something from {/dev/sda1}", + "Create larger partition.", + ], + parameters={"device": "/dev/sda1"}, + ), + "name", + "E-TEST-1", + ), + ( + Error( + code="E-TEST-1", + message="Not enough space on device {/dev/sda1}.", + mitigations=[ + "Delete something from {/dev/sda1}", + "Create larger partition.", + ], + parameters={"device": "/dev/sda1"}, + ), + "message", + "['Not enough space on device {/dev/sda1}.']", + ), + ( + Error( + code="E-TEST-1", + message="Not enough space on device {/dev/sda1}.", + mitigations=[ + "Delete something from {/dev/sda1}", + "Create larger partition.", + ], + parameters={"device": "/dev/sda1"}, + ), + "mitigations", + "['Delete something from {/dev/sda1}', 'Create larger partition.']", + ), + ( + Error( + code="E-TEST-1", + message="Not enough space on device {/dev/sda1}.", + mitigations=[ + "Delete something from {/dev/sda1}", + "Create larger partition.", + ], + parameters={"device": "/dev/sda1"}, + ), + "parameters", + "{'device': '/dev/sda1'}", + ), + ( + Error( + code="E-TEST-1", + message="Not enough space on device {/dev/sda1}.", + mitigations=[ + "Delete something from {/dev/sda1}", + "Create larger partition.", + ], + parameters={"device": "/dev/sda1"}, + ), + "parameters mitigations message name", + "{'device': '/dev/sda1'} ['Delete something from {/dev/sda1}', 'Create larger partition.'] ['Not enough space on device {/dev/sda1}.'] E-TEST-1", + ), + ], +) +def test_fmt(error, fmt, expected): + fmt_str = f"{{error:{fmt}}}" + actual = fmt_str.format(error=error) + assert actual == expected