Skip to content

Commit

Permalink
feat(Client): improve httpx errors handling (#1662)
Browse files Browse the repository at this point in the history
* handle inaccessible api_url exception

* handle api exception via decorator.

* return result from decorator

(cherry picked from commit 56b8829)

fix: tackle with new error wrapper
  • Loading branch information
Ankush-Chander authored and frascuchon committed Oct 5, 2022
1 parent 0b94c86 commit 85da336
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 8 deletions.
6 changes: 4 additions & 2 deletions src/rubrix/client/api.py
Expand Up @@ -149,8 +149,10 @@ def __init__(
self._agent = _RubrixLogAgent(self)

def __del__(self):
del self._client
del self._agent
if hasattr(self,"_client"):
del self._client
if hasattr(self,"_agent"):
del self._agent

@property
def client(self):
Expand Down
17 changes: 17 additions & 0 deletions src/rubrix/client/sdk/client.py
Expand Up @@ -13,12 +13,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import dataclasses
import functools
from typing import Dict, TypeVar

import httpx

from rubrix._constants import API_KEY_HEADER_NAME
from rubrix.client.sdk._helpers import build_raw_response
from rubrix.client.sdk.commons.errors import RubrixClientError


@dataclasses.dataclass
Expand Down Expand Up @@ -72,6 +74,18 @@ def __del__(self):
def __hash__(self):
return hash(self.base_url)

def with_httpx_error_handler(func):
@functools.wraps(func)
def inner(self, *args, **kwargs):
try:
result = func(self, *args, **kwargs)
return result
except httpx.ConnectError as err:
err_str = f"Your Api endpoint at {self.base_url} is not available or not responding."
raise RubrixClientError(err_str) from None
return inner

@with_httpx_error_handler
def get(self, path: str, *args, **kwargs):
path = self._normalize_path(path)
response = self.__httpx__.get(
Expand All @@ -82,6 +96,7 @@ def get(self, path: str, *args, **kwargs):
)
return build_raw_response(response).parsed

@with_httpx_error_handler
def post(self, path: str, *args, **kwargs):
path = self._normalize_path(path)

Expand All @@ -93,6 +108,7 @@ def post(self, path: str, *args, **kwargs):
)
return build_raw_response(response).parsed

@with_httpx_error_handler
def put(self, path: str, *args, **kwargs):
path = self._normalize_path(path)
response = self.__httpx__.put(
Expand All @@ -103,6 +119,7 @@ def put(self, path: str, *args, **kwargs):
)
return build_raw_response(response).parsed

@with_httpx_error_handler
def stream(self, path: str, *args, **kwargs):
return self.__httpx__.stream(
url=path,
Expand Down
9 changes: 5 additions & 4 deletions src/rubrix/server/server.py
Expand Up @@ -27,7 +27,10 @@

from rubrix import __version__ as rubrix_version
from rubrix.logging import configure_logging
from rubrix.server.daos.backend.elasticsearch import ElasticsearchBackend
from rubrix.server.daos.backend.elasticsearch import (
ElasticsearchBackend,
GenericSearchError,
)
from rubrix.server.daos.datasets import DatasetsDAO
from rubrix.server.daos.records import DatasetRecordsDAO
from rubrix.server.errors import APIErrorHandler, EntityNotFoundError
Expand Down Expand Up @@ -86,8 +89,6 @@ def configure_app_statics(app: FastAPI):
def configure_app_storage(app: FastAPI):
@app.on_event("startup")
async def configure_elasticsearch():
import opensearchpy

try:
es_wrapper = ElasticsearchBackend.get_instance()
dataset_records: DatasetRecordsDAO = DatasetRecordsDAO(es_wrapper)
Expand All @@ -96,7 +97,7 @@ async def configure_elasticsearch():
)
datasets.init()
dataset_records.init()
except opensearchpy.exceptions.ConnectionError as error:
except GenericSearchError as error:
raise ConfigError(
f"Your Elasticsearch endpoint at {settings.obfuscated_elasticsearch()} "
"is not available or not responding.\n"
Expand Down
4 changes: 2 additions & 2 deletions tests/client/sdk/users/test_api.py
Expand Up @@ -3,7 +3,7 @@

from rubrix._constants import DEFAULT_API_KEY
from rubrix.client.sdk.client import AuthenticatedClient
from rubrix.client.sdk.commons.errors import UnauthorizedApiError
from rubrix.client.sdk.commons.errors import RubrixClientError, UnauthorizedApiError
from rubrix.client.sdk.users.api import whoami
from rubrix.client.sdk.users.models import User

Expand All @@ -23,7 +23,7 @@ def test_whoami_with_auth_error(monkeypatch, mocked_client):


def test_whoami_with_connection_error():
with pytest.raises(httpx.ConnectError):
with pytest.raises(RubrixClientError):
whoami(
AuthenticatedClient(base_url="http://localhost:6900", token="wrong-apikey")
)

0 comments on commit 85da336

Please sign in to comment.