Skip to content

Commit

Permalink
Include parsed error info in TransportError in async connections
Browse files Browse the repository at this point in the history
Passing the Content-Type to `_raise_errors` will cause the json body to
be parsed and included in the `TransportError`.

This matches the behaviour of the sync client.

Fixes #225

Signed-off-by: Gordon Govan <gg@kialo.com>
  • Loading branch information
gg-kialo committed May 8, 2023
1 parent 2abb8c4 commit caab1c3
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
### Fixed
- Fixed import cycle when importing async helpers ([#311](https://github.com/opensearch-project/opensearch-py/pull/311))
- Fixed userguide for async client ([#340](https://github.com/opensearch-project/opensearch-py/pull/340))
- Include parsed error info in TransportError in async connections (fixes #225) ([#226](https://github.com/opensearch-project/opensearch-py/pull/226)
### Security
- Fixed CVE-2022-23491 reported in opensearch-dsl-py ([#295](https://github.com/opensearch-project/opensearch-py/pull/295))
- Update ci workflows ([#318](https://github.com/opensearch-project/opensearch-py/pull/318))
Expand Down
6 changes: 5 additions & 1 deletion opensearchpy/_async/http_aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,11 @@ async def perform_request(
status_code=response.status,
response=raw_data,
)
self._raise_error(response.status, raw_data)
self._raise_error(
response.status,
raw_data,
response.headers.get("content-type"),
)

self.log_request_success(
method, str(url), url_path, orig_body, response.status, raw_data, duration
Expand Down
28 changes: 24 additions & 4 deletions test_opensearchpy/test_async/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
from opensearchpy import AIOHttpConnection, AsyncOpenSearch, __versionstr__, serializer
from opensearchpy.compat import reraise_exceptions
from opensearchpy.connection import Connection, async_connections
from opensearchpy.exceptions import ConnectionError
from opensearchpy.exceptions import ConnectionError, TransportError

pytestmark = pytest.mark.asyncio

Expand All @@ -53,7 +53,13 @@ def gzip_decompress(data):


class TestAIOHttpConnection:
async def _get_mock_connection(self, connection_params={}, response_body=b"{}"):
async def _get_mock_connection(
self,
connection_params={},
response_code=200,
response_body=b"{}",
response_headers={},
):
con = AIOHttpConnection(**connection_params)
await con._create_aiohttp_session()

Expand All @@ -69,8 +75,8 @@ async def text(self):
return response_body.decode("utf-8", "surrogatepass")

dummy_response = DummyResponse()
dummy_response.headers = CIMultiDict()
dummy_response.status = 200
dummy_response.headers = CIMultiDict(**response_headers)
dummy_response.status = response_code
_dummy_request.call_args = (args, kwargs)
return dummy_response

Expand Down Expand Up @@ -298,6 +304,20 @@ def request_raise(*_, **__):
await conn.perform_request("GET", "/")
assert str(e.value) == "Wasn't modified!"

async def test_json_errors_are_parsed(self):
con = await self._get_mock_connection(
response_code=400,
response_body=b'{"error": {"type": "snapshot_in_progress_exception"}}',
response_headers={"Content-Type": "application/json;"},
)
try:
with pytest.raises(TransportError) as e:
await con.perform_request("POST", "/", body=b'{"some": "json"')

assert e.value.error == "snapshot_in_progress_exception"
finally:
await con.close()


class TestConnectionHttpbin:
"""Tests the HTTP connection implementations against a live server E2E"""
Expand Down

0 comments on commit caab1c3

Please sign in to comment.