diff --git a/meilisearch/errors.py b/meilisearch/errors.py index 57ca2bc2..87583b1c 100644 --- a/meilisearch/errors.py +++ b/meilisearch/errors.py @@ -35,11 +35,17 @@ def __init__(self, error: str, request: Response) -> None: self.type = None if request.text: - json_data = json.loads(request.text) - self.message = json_data.get("message") - self.code = json_data.get("code") - self.link = json_data.get("link") - self.type = json_data.get("type") + try: + json_data = json.loads(request.text) + if isinstance(json_data, dict): + self.message = json_data.get("message") or request.text + self.code = json_data.get("code") + self.link = json_data.get("link") + self.type = json_data.get("type") + else: + self.message = request.text + except json.JSONDecodeError: + self.message = request.text else: self.message = error super().__init__(self.message) diff --git a/tests/errors/test_api_error_meilisearch.py b/tests/errors/test_api_error_meilisearch.py index 0c91aeeb..e80e962c 100644 --- a/tests/errors/test_api_error_meilisearch.py +++ b/tests/errors/test_api_error_meilisearch.py @@ -35,6 +35,46 @@ def test_meilisearch_api_error_no_code(mock_post): client.create_index("some_index") +@patch("requests.post") +def test_meilisearch_api_error_falls_back_to_raw_message_for_non_json_response(mock_post): + """Uses raw response text when an API error body is not valid JSON.""" + mock_post.configure_mock(__name__="post") + mock_response = requests.models.Response() + mock_response.status_code = 502 + mock_response._content = b"Bad Gateway" # pylint: disable=protected-access + mock_post.return_value = mock_response + + with pytest.raises(MeilisearchApiError) as exc: + client = meilisearch.Client(BASE_URL, MASTER_KEY + "123") + client.create_index("some_index") + + assert exc.value.status_code == 502 + assert exc.value.message == "Bad Gateway" + assert exc.value.code is None + assert exc.value.link is None + assert exc.value.type is None + + +@patch("requests.post") +def test_meilisearch_api_error_falls_back_to_raw_message_for_non_object_json_response(mock_post): + """Uses raw response text when parsed JSON is not an object.""" + mock_post.configure_mock(__name__="post") + mock_response = requests.models.Response() + mock_response.status_code = 502 + mock_response._content = b'["Bad Gateway"]' # pylint: disable=protected-access + mock_post.return_value = mock_response + + with pytest.raises(MeilisearchApiError) as exc: + client = meilisearch.Client(BASE_URL, MASTER_KEY + "123") + client.create_index("some_index") + + assert exc.value.status_code == 502 + assert exc.value.message == '["Bad Gateway"]' + assert exc.value.code is None + assert exc.value.link is None + assert exc.value.type is None + + def test_version_error_hint_message(): mock_response = requests.models.Response() mock_response.status_code = 408