Skip to content
Snippets Groups Projects
Commit a0e61ab8 authored by vlorentz's avatar vlorentz
Browse files

Make the RPC client raise a specific exception class on 503

This will be used to make the storage retry proxy retry harder
when the storage server raises errors like psycopg2.OperationalError;
which last longer than we want the proxy to retry for typical
exceptions.
parent 9848432c
No related branches found
Tags v2.14.0
1 merge request!289Make the RPC client raise a specific exception class on 503
......@@ -121,6 +121,12 @@ class RemoteException(Exception):
return super().__str__()
class TransientRemoteException(RemoteException):
"""Subclass of RemoteException representing errors which are expected
to be temporary.
"""
F = TypeVar("F", bound=Callable)
......@@ -334,8 +340,16 @@ class RPCClient(metaclass=MetaRPCClient):
exception = RemoteException(payload=exc_data, response=response)
elif status_class == 5:
cls: Type[RemoteException]
if status_code == 503:
# This isn't a generic HTTP client and we know the server does
# not support the Retry-After header, so we do not implement
# it here either.
cls = TransientRemoteException
else:
cls = RemoteException
exc_data = self._decode_response(response, check_status=False)
exception = RemoteException(payload=exc_data, response=response)
exception = cls(payload=exc_data, response=response)
if exception:
raise exception from None
......
......@@ -8,7 +8,13 @@ import re
import pytest
from requests.exceptions import ConnectionError
from swh.core.api import APIError, RemoteException, RPCClient, remote_api_endpoint
from swh.core.api import (
APIError,
RemoteException,
RPCClient,
TransientRemoteException,
remote_api_endpoint,
)
from swh.core.api.serializers import exception_to_dict, msgpack_dumps
from .test_serializers import ExtraType, extra_decoders, extra_encoders
......@@ -143,7 +149,7 @@ def test_client_reraise_exception(rpc_client, requests_mock):
assert str(exc_info.value) == error_message
@pytest.mark.parametrize("status_code", [400, 500])
@pytest.mark.parametrize("status_code", [400, 500, 503])
def test_client_raise_remote_exception(rpc_client, requests_mock, status_code):
"""
Exception caught server-side and not whitelisted will be wrapped and raised
......@@ -165,3 +171,7 @@ def test_client_raise_remote_exception(rpc_client, requests_mock, status_code):
assert str(exc_info.value.args[0]["type"]) == "Exception"
assert str(exc_info.value.args[0]["message"]) == error_message
if status_code == 503:
assert isinstance(exc_info.value, TransientRemoteException)
else:
assert not isinstance(exc_info.value, TransientRemoteException)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment