diff --git a/swh/core/api/serializers.py b/swh/core/api/serializers.py --- a/swh/core/api/serializers.py +++ b/swh/core/api/serializers.py @@ -53,7 +53,11 @@ def dict_to_exception(exc_dict: Dict[str, Any]) -> Exception: temp = __import__(exc_dict["module"], fromlist=[exc_dict["type"]]) - return getattr(temp, exc_dict["type"])(*exc_dict["args"]) + try: + return getattr(temp, exc_dict["type"])(*exc_dict["args"]) + except Exception: + # custom Exception type cannot be rebuilt, fallback to base Exception type + return Exception(exc_dict["message"]) def encode_timedelta(td: datetime.timedelta) -> Dict[str, int]: diff --git a/swh/core/api/tests/test_serializers.py b/swh/core/api/tests/test_serializers.py --- a/swh/core/api/tests/test_serializers.py +++ b/swh/core/api/tests/test_serializers.py @@ -131,6 +131,12 @@ } +class ComplexExceptionType(Exception): + def __init__(self, error_type, message): + self.error_type = error_type + super().__init__(f"{error_type}: {message}") + + def test_serializers_round_trip_json(): json_data = json_dumps(DATA) actual_data = json_loads(json_data) @@ -153,6 +159,15 @@ assert str(actual_data["exception"]) == error_message +def test_complex_exception_serializer_round_trip_json(): + exception = ComplexExceptionType("NotFound", "the object is missing") + json_data = json_dumps({"exception": exception}) + actual_data = json_loads(json_data) + assert "exception" in actual_data + assert type(actual_data["exception"]) == Exception + assert str(actual_data["exception"]) == str(exception) + + def test_serializers_encode_swh_json(): json_str = json_dumps(DATA) actual_data = json.loads(json_str) @@ -187,6 +202,15 @@ assert str(actual_data["exception"]) == error_message +def test_complex_exception_serializer_round_trip_msgpack(): + exception = ComplexExceptionType("NotFound", "the object is missing") + data = msgpack_dumps({"exception": exception}) + actual_data = msgpack_loads(data) + assert "exception" in actual_data + assert type(actual_data["exception"]) == Exception + assert str(actual_data["exception"]) == str(exception) + + def test_serializers_generator_json(): data = json_dumps((i for i in range(5))) assert json_loads(data) == [i for i in range(5)]