From a6ce69ddc907b9fce99bca8dbcbfde6aedb29a48 Mon Sep 17 00:00:00 2001 From: CRDong233 <3105897713@qq.com> Date: Mon, 17 Aug 2026 22:46:22 +0800 Subject: [PATCH] fix: include request URL in unexpected response --- qdrant_client/http/exceptions.py | 27 +++++++++++++++++++++++---- tests/test_http_exceptions.py | 24 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 tests/test_http_exceptions.py diff --git a/qdrant_client/http/exceptions.py b/qdrant_client/http/exceptions.py index 45437e1c0..b10604021 100644 --- a/qdrant_client/http/exceptions.py +++ b/qdrant_client/http/exceptions.py @@ -11,19 +11,33 @@ class ApiException(Exception): class UnexpectedResponse(ApiException): - def __init__(self, status_code: Optional[int], reason_phrase: str, content: bytes, headers: Headers) -> None: + def __init__( + self, + status_code: Optional[int], + reason_phrase: str, + content: bytes, + headers: Headers, + url: Optional[str] = None, + ) -> None: self.status_code = status_code self.reason_phrase = reason_phrase self.content = content self.headers = headers + self.url = url @staticmethod - def for_response(response: Response) -> "ApiException": + def for_response(response: Response) -> "UnexpectedResponse": + try: + url = str(response.request.url) + except RuntimeError: + url = None + return UnexpectedResponse( status_code=response.status_code, reason_phrase=response.reason_phrase, content=response.content, headers=response.headers, + url=url, ) def __str__(self) -> str: @@ -33,9 +47,14 @@ def __str__(self) -> str: else: reason_phrase_str = f"({self.reason_phrase})" status_str = f"{status_code_str} {reason_phrase_str}".strip() - short_content = self.content if len(self.content) <= MAX_CONTENT else self.content[: MAX_CONTENT - 3] + b" ..." + short_content = ( + self.content + if len(self.content) <= MAX_CONTENT + else self.content[: MAX_CONTENT - 3] + b" ..." + ) + request_url_str = f"Request URL: {self.url}\n" if self.url else "" raw_content_str = f"Raw response content:\n{short_content!r}" - return f"Unexpected Response: {status_str}\n{raw_content_str}" + return f"Unexpected Response: {status_str}\n{request_url_str}{raw_content_str}" def structured(self) -> Dict[str, Any]: return json.loads(self.content) diff --git a/tests/test_http_exceptions.py b/tests/test_http_exceptions.py new file mode 100644 index 000000000..2b6b722e3 --- /dev/null +++ b/tests/test_http_exceptions.py @@ -0,0 +1,24 @@ +from httpx import Request, Response + +from qdrant_client.http.exceptions import UnexpectedResponse + + +def test_unexpected_response_includes_request_url(): + request = Request("POST", "https://example.com/api/collections?wait=true") + response = Response(404, request=request, content=b"not found") + + exception = UnexpectedResponse.for_response(response) + + assert exception.url == "https://example.com/api/collections?wait=true" + assert "Request URL: https://example.com/api/collections?wait=true" in str( + exception + ) + + +def test_unexpected_response_without_request_omits_url(): + response = Response(404, content=b"not found") + + exception = UnexpectedResponse.for_response(response) + + assert exception.url is None + assert "Request URL:" not in str(exception)