Skip to content

Commit e656c44

Browse files
committed
test: cover every client-local error on both clients (#143)
1 parent d1fca84 commit e656c44

1 file changed

Lines changed: 59 additions & 0 deletions

File tree

‎tests/api_call_test.py‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from tests.utils.object_assertions import assert_match_object, assert_object_lists_match
2020
from typesense import exceptions
2121
from typesense.sync.api_call import ApiCall, RequestHandler
22+
from typesense.async_.api_call import AsyncApiCall
2223
from typesense.configuration import Configuration, Node
2324
from typesense.logger import logger
2425

@@ -634,3 +635,61 @@ def test_max_retries_no_last_exception(fake_api_call: ApiCall) -> None:
634635
num_retries=10,
635636
last_exception=None,
636637
)
638+
639+
640+
@pytest.mark.parametrize(
641+
"client_side_error",
642+
[
643+
httpx.PoolTimeout("Pool timeout"),
644+
httpx.LocalProtocolError("Local protocol error"),
645+
httpx.DecodingError("Decoding error"),
646+
httpx.TooManyRedirects("Too many redirects"),
647+
],
648+
)
649+
def test_client_side_error_does_not_mark_node_unhealthy(
650+
fake_api_call: ApiCall,
651+
client_side_error: httpx.HTTPError,
652+
) -> None:
653+
"""Test that client-side httpx errors propagate without failing over."""
654+
with respx.mock:
655+
respx.get("http://nearest:8108/").mock(side_effect=client_side_error)
656+
node0_route = respx.get("http://node0:8108/").mock(
657+
return_value=httpx.Response(200, json={"key": "value"}),
658+
)
659+
660+
with pytest.raises(type(client_side_error)):
661+
fake_api_call.get("/", entity_type=typing.Dict[str, str])
662+
663+
assert len(respx.calls) == 1
664+
assert not node0_route.called
665+
666+
assert fake_api_call.config.nearest_node.healthy is True
667+
668+
669+
@pytest.mark.parametrize(
670+
"client_side_error",
671+
[
672+
httpx.PoolTimeout("Pool timeout"),
673+
httpx.LocalProtocolError("Local protocol error"),
674+
httpx.DecodingError("Decoding error"),
675+
httpx.TooManyRedirects("Too many redirects"),
676+
],
677+
)
678+
async def test_async_client_side_error_does_not_mark_node_unhealthy(
679+
fake_async_api_call: AsyncApiCall,
680+
client_side_error: httpx.HTTPError,
681+
) -> None:
682+
"""Test that client-side httpx errors propagate without failing over (async)."""
683+
with respx.mock:
684+
respx.get("http://nearest:8108/").mock(side_effect=client_side_error)
685+
node0_route = respx.get("http://node0:8108/").mock(
686+
return_value=httpx.Response(200, json={"key": "value"}),
687+
)
688+
689+
with pytest.raises(type(client_side_error)):
690+
await fake_async_api_call.get("/", entity_type=typing.Dict[str, str])
691+
692+
assert len(respx.calls) == 1
693+
assert not node0_route.called
694+
695+
assert fake_async_api_call.config.nearest_node.healthy is True

0 commit comments

Comments
 (0)