diff --git a/libp2p/exceptions.py b/libp2p/exceptions.py index 5b781145..f4f80b5f 100644 --- a/libp2p/exceptions.py +++ b/libp2p/exceptions.py @@ -1,3 +1,8 @@ +from collections.abc import ( + Sequence, +) + + class BaseLibp2pError(Exception): pass @@ -11,6 +16,38 @@ class ParseError(BaseLibp2pError): class MultiError(BaseLibp2pError): - """Raised with multiple exceptions.""" + r""" + A combined error that wraps multiple exceptions into a single error object. + This error is raised when multiple exceptions need to be reported together, + typically in scenarios where parallel operations or multiple validations fail. - # todo: find some way for this to fancy-print all encapsulated errors + Example\: + --------- + >>> from libp2p.exceptions import MultiError + >>> errors = [ + ... ValueError("Invalid input"), + ... TypeError("Wrong type"), + ... RuntimeError("Operation failed") + ... ] + >>> multi_error = MultiError(errors) + >>> print(multi_error) + Error 1: Invalid input + Error 2: Wrong type + Error 3: Operation failed + + Note\: + ------ + The string representation of this error will number and list all contained + errors sequentially, making it easier to identify individual issues in + complex error scenarios. + + """ + + def __init__(self, errors: Sequence[Exception]) -> None: + super().__init__(errors) + self.errors = errors # Storing list of errors + + def __str__(self) -> str: + return "\n".join( + f"Error {i + 1}: {error}" for i, error in enumerate(self.errors) + ) diff --git a/newsfragments/613.feature.rst b/newsfragments/613.feature.rst new file mode 100644 index 00000000..1406ae40 --- /dev/null +++ b/newsfragments/613.feature.rst @@ -0,0 +1 @@ +Added support for multiple-error formatting in the `MultiError` class. diff --git a/tests/exceptions/test_exceptions.py b/tests/exceptions/test_exceptions.py new file mode 100644 index 00000000..09849c6d --- /dev/null +++ b/tests/exceptions/test_exceptions.py @@ -0,0 +1,13 @@ +from libp2p.exceptions import ( + MultiError, +) + + +def test_multierror_str_and_storage(): + errors = [ValueError("bad value"), KeyError("missing key"), "custom error"] + multi_error = MultiError(errors) + # Check for storage + assert multi_error.errors == errors + # Check for representation + expected = "Error 1: bad value\n" "Error 2: 'missing key'\n" "Error 3: custom error" + assert str(multi_error) == expected