diff --git a/swh/core/api/__init__.py b/swh/core/api/__init__.py --- a/swh/core/api/__init__.py +++ b/swh/core/api/__init__.py @@ -250,22 +250,27 @@ if status_code == 404: raise RemoteException(payload='404 not found', response=response) + exception = None + try: if status_class == 4: data = decode_response(response) - raise pickle.loads(data) + exception = pickle.loads(data) - if status_class == 5: + elif status_class == 5: data = decode_response(response) if 'exception_pickled' in data: - raise pickle.loads(data['exception_pickled']) + exception = pickle.loads(data['exception_pickled']) else: - raise RemoteException(payload=data['exception'], - response=response) + exception = RemoteException(payload=data['exception'], + response=response) except (TypeError, pickle.UnpicklingError): raise RemoteException(payload=data, response=response) + if exception: + raise exception from None + if status_class != 2: raise RemoteException( payload=f'API HTTP error: {status_code} {response.content}', diff --git a/swh/core/api/tests/test_rpc_client_server.py b/swh/core/api/tests/test_rpc_client_server.py --- a/swh/core/api/tests/test_rpc_client_server.py +++ b/swh/core/api/tests/test_rpc_client_server.py @@ -20,6 +20,10 @@ def something(self, data, db=None, cur=None): return data + @remote_api_endpoint('raises_typeerror') + def raise_typeerror(self): + raise TypeError('Did I pass through?') + # this class is used on the client part. We cannot inherit from RPCTest # because the automagic metaclass based code that generates the RPCClient @@ -40,6 +44,10 @@ def not_on_server(self, db=None, cur=None): return 'ok' + @remote_api_endpoint('raises_typeerror') + def raise_typeerror(self): + return 'data' + class RPCTestClient(RPCClient): backend_class = RPCTest2 @@ -87,3 +95,8 @@ assert res == 'whatever' res = swh_rpc_client.endpoint('spam') assert res == 'egg' + + +def test_api_typeerror(swh_rpc_client): + with pytest.raises(TypeError, match='Did I pass through?'): + swh_rpc_client.raise_typeerror()