diff --git a/swh/storage/api/client.py b/swh/storage/api/client.py --- a/swh/storage/api/client.py +++ b/swh/storage/api/client.py @@ -3,9 +3,10 @@ # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information -from swh.core.api import RPCClient +from swh.core.api import RPCClient, RemoteException -from ..exc import StorageAPIError +from .. import HashCollision +from ..exc import StorageAPIError, StorageArgumentException from ..interface import StorageInterface @@ -14,6 +15,25 @@ api_exception = StorageAPIError backend_class = StorageInterface + def raise_for_status(self, response) -> None: + try: + super().raise_for_status(response) + except RemoteException as e: + if e.response and e.response.status_code == 400: + assert e.args[0]['type'] \ + == 'StorageArgumentException' + raise StorageArgumentException( + *e.args[0]['args']) + elif e.response and e.response.status_code == 500 and e.args \ + and e.args[0].get('type') == 'HashCollision': + # XXX: workaround until we fix these HashCollisions happening + # when they shouldn't + raise HashCollision( + *e.args[0]['args']) + else: + print(e.args) + raise + def reset(self): return self.post('reset', {}) diff --git a/swh/storage/api/server.py b/swh/storage/api/server.py --- a/swh/storage/api/server.py +++ b/swh/storage/api/server.py @@ -14,6 +14,7 @@ from ..interface import StorageInterface from ..metrics import timed +from ..exc import StorageArgumentException def get_storage(): @@ -30,6 +31,11 @@ storage = None +@app.errorhandler(StorageArgumentException) +def argument_error_handler(exception): + return error_handler(exception, encode_data, status_code=400) + + @app.errorhandler(Exception) def my_error_handler(exception): return error_handler(exception, encode_data)