Changeset View
Changeset View
Standalone View
Standalone View
swh/core/api/__init__.py
# Copyright (C) 2015-2020 The Software Heritage developers | # Copyright (C) 2015-2022 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
from collections import abc | from collections import abc | ||||
import functools | import functools | ||||
import inspect | import inspect | ||||
import logging | import logging | ||||
import pickle | |||||
from typing import ( | from typing import ( | ||||
Any, | Any, | ||||
Callable, | Callable, | ||||
ClassVar, | ClassVar, | ||||
Dict, | Dict, | ||||
List, | List, | ||||
Optional, | Optional, | ||||
Tuple, | Tuple, | ||||
▲ Show 20 Lines • Show All 301 Lines • ▼ Show 20 Lines | def raise_for_status(self, response) -> None: | ||||
status_code = response.status_code | status_code = response.status_code | ||||
status_class = response.status_code // 100 | status_class = response.status_code // 100 | ||||
if status_code == 404: | if status_code == 404: | ||||
raise RemoteException(payload="404 not found", response=response) | raise RemoteException(payload="404 not found", response=response) | ||||
exception = None | exception = None | ||||
# TODO: only old servers send pickled error; stop trying to unpickle | |||||
# after they are all upgraded | |||||
try: | |||||
if status_class == 4: | if status_class == 4: | ||||
data = self._decode_response(response, check_status=False) | exc_data = self._decode_response(response, check_status=False) | ||||
if isinstance(data, dict): | |||||
# TODO: remove "exception" key check once all servers | |||||
# are using new schema | |||||
exc_data = data["exception"] if "exception" in data else data | |||||
for exc_type in self.reraise_exceptions: | for exc_type in self.reraise_exceptions: | ||||
if exc_type.__name__ == exc_data["type"]: | if exc_type.__name__ == exc_data["type"]: | ||||
exception = exc_type(*exc_data["args"]) | exception = exc_type(*exc_data["args"]) | ||||
break | break | ||||
else: | else: | ||||
exception = RemoteException(payload=exc_data, response=response) | exception = RemoteException(payload=exc_data, response=response) | ||||
else: | |||||
exception = pickle.loads(data) | |||||
elif status_class == 5: | elif status_class == 5: | ||||
data = self._decode_response(response, check_status=False) | exc_data = self._decode_response(response, check_status=False) | ||||
if "exception_pickled" in data: | |||||
exception = pickle.loads(data["exception_pickled"]) | |||||
else: | |||||
# TODO: remove "exception" key check once all servers | |||||
# are using new schema | |||||
exc_data = data["exception"] if "exception" in data else data | |||||
exception = RemoteException(payload=exc_data, response=response) | exception = RemoteException(payload=exc_data, response=response) | ||||
except (TypeError, pickle.UnpicklingError): | |||||
anlambert: Are you sure we do not need to catch the `TypeError` anymore ? Is it not thrown by `self. | |||||
Done Inline ActionsI can't think of a way to trigger it vlorentz: I can't think of a way to trigger it | |||||
raise RemoteException(payload=data, response=response) | |||||
if exception: | if exception: | ||||
raise exception from None | raise exception from None | ||||
if status_class != 2: | if status_class != 2: | ||||
raise RemoteException( | raise RemoteException( | ||||
payload=f"API HTTP error: {status_code} {response.content}", | payload=f"API HTTP error: {status_code} {response.content}", | ||||
response=response, | response=response, | ||||
) | ) | ||||
▲ Show 20 Lines • Show All 153 Lines • Show Last 20 Lines |
Are you sure we do not need to catch the TypeError anymore ? Is it not thrown by self._decode_response ?