From 28cc739a9395e1a2115dff5bdac6fcb941ade8bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=BD=E5=B0=98?= Date: Tue, 16 Jun 2026 16:16:34 +0800 Subject: [PATCH] fix(jina): handle non-json auth errors (#37502) --- api/services/auth/jina.py | 10 ++++-- api/services/auth/jina/jina.py | 10 ++++-- .../services/auth/test_jina_auth.py | 32 +++++++++++++++++++ .../auth/test_jina_auth_standalone_module.py | 21 ++++++++++++ 4 files changed, 69 insertions(+), 4 deletions(-) diff --git a/api/services/auth/jina.py b/api/services/auth/jina.py index 0b49b88e98..c5e9ac2d1c 100644 --- a/api/services/auth/jina.py +++ b/api/services/auth/jina.py @@ -43,10 +43,16 @@ class JinaAuth(ApiKeyAuthBase): def _handle_error(self, response): if response.status_code in {402, 409, 500}: - error_message = response.json().get("error", "Unknown error occurred") + try: + error_message = response.json().get("error", "Unknown error occurred") + except ValueError: + error_message = response.text or "Unknown error occurred" raise Exception(f"Failed to authorize. Status code: {response.status_code}. Error: {error_message}") else: if response.text: - error_message = json.loads(response.text).get("error", "Unknown error occurred") + try: + error_message = json.loads(response.text).get("error", "Unknown error occurred") + except ValueError: + error_message = response.text raise Exception(f"Failed to authorize. Status code: {response.status_code}. Error: {error_message}") raise Exception(f"Unexpected error occurred while trying to authorize. Status code: {response.status_code}") diff --git a/api/services/auth/jina/jina.py b/api/services/auth/jina/jina.py index d8d2fd51c0..6260b6b48a 100644 --- a/api/services/auth/jina/jina.py +++ b/api/services/auth/jina/jina.py @@ -43,10 +43,16 @@ class JinaAuth(ApiKeyAuthBase): def _handle_error(self, response): if response.status_code in {402, 409, 500}: - error_message = response.json().get("error", "Unknown error occurred") + try: + error_message = response.json().get("error", "Unknown error occurred") + except ValueError: + error_message = response.text or "Unknown error occurred" raise Exception(f"Failed to authorize. Status code: {response.status_code}. Error: {error_message}") else: if response.text: - error_message = json.loads(response.text).get("error", "Unknown error occurred") + try: + error_message = json.loads(response.text).get("error", "Unknown error occurred") + except ValueError: + error_message = response.text raise Exception(f"Failed to authorize. Status code: {response.status_code}. Error: {error_message}") raise Exception(f"Unexpected error occurred while trying to authorize. Status code: {response.status_code}") diff --git a/api/tests/unit_tests/services/auth/test_jina_auth.py b/api/tests/unit_tests/services/auth/test_jina_auth.py index 2c34d46f1e..eb409c61d4 100644 --- a/api/tests/unit_tests/services/auth/test_jina_auth.py +++ b/api/tests/unit_tests/services/auth/test_jina_auth.py @@ -68,6 +68,22 @@ class TestJinaAuth: auth.validate_credentials() assert str(exc_info.value) == "Failed to authorize. Status code: 402. Error: Payment required" + @patch("services.auth.jina.jina._http_client.post", autospec=True) + def test_should_handle_http_error_with_non_json_text_response(self, mock_post): + """Test handling of known HTTP errors with non-JSON text response.""" + mock_response = MagicMock() + mock_response.status_code = 402 + mock_response.text = "Payment required" + mock_response.json.side_effect = ValueError("Not JSON") + mock_post.return_value = mock_response + + credentials = {"auth_type": "bearer", "config": {"api_key": "test_api_key_123"}} + auth = JinaAuth(credentials) + + with pytest.raises(Exception) as exc_info: + auth.validate_credentials() + assert str(exc_info.value) == "Failed to authorize. Status code: 402. Error: Payment required" + @patch("services.auth.jina.jina._http_client.post", autospec=True) def test_should_handle_http_409_error(self, mock_post): """Test handling of 409 Conflict error""" @@ -114,6 +130,22 @@ class TestJinaAuth: auth.validate_credentials() assert str(exc_info.value) == "Failed to authorize. Status code: 403. Error: Forbidden" + @patch("services.auth.jina.jina._http_client.post", autospec=True) + def test_should_handle_unexpected_error_with_non_json_text_response(self, mock_post): + """Test handling of unexpected errors with non-JSON text response.""" + mock_response = MagicMock() + mock_response.status_code = 403 + mock_response.text = "Forbidden" + mock_response.json.side_effect = Exception("Not JSON") + mock_post.return_value = mock_response + + credentials = {"auth_type": "bearer", "config": {"api_key": "test_api_key_123"}} + auth = JinaAuth(credentials) + + with pytest.raises(Exception) as exc_info: + auth.validate_credentials() + assert str(exc_info.value) == "Failed to authorize. Status code: 403. Error: Forbidden" + @patch("services.auth.jina.jina._http_client.post", autospec=True) def test_should_handle_unexpected_error_without_text(self, mock_post): """Test handling of unexpected errors without text response""" diff --git a/api/tests/unit_tests/services/auth/test_jina_auth_standalone_module.py b/api/tests/unit_tests/services/auth/test_jina_auth_standalone_module.py index b31af996ae..9e45cbbd94 100644 --- a/api/tests/unit_tests/services/auth/test_jina_auth_standalone_module.py +++ b/api/tests/unit_tests/services/auth/test_jina_auth_standalone_module.py @@ -118,6 +118,17 @@ def test_handle_error_statuses_default_unknown_error(jina_module: ModuleType) -> auth._handle_error(response) +def test_handle_error_statuses_fall_back_to_text_body(jina_module: ModuleType) -> None: + auth = jina_module.JinaAuth(_credentials(api_key="k")) + response = MagicMock() + response.status_code = 402 + response.text = "Payment required" + response.json.side_effect = ValueError("Not JSON") + + with pytest.raises(Exception, match="Status code: 402.*Payment required"): + auth._handle_error(response) + + def test_handle_error_with_text_json_body(jina_module: ModuleType) -> None: auth = jina_module.JinaAuth(_credentials(api_key="k")) response = MagicMock() @@ -128,6 +139,16 @@ def test_handle_error_with_text_json_body(jina_module: ModuleType) -> None: auth._handle_error(response) +def test_handle_error_with_non_json_text_body(jina_module: ModuleType) -> None: + auth = jina_module.JinaAuth(_credentials(api_key="k")) + response = MagicMock() + response.status_code = 403 + response.text = "Forbidden" + + with pytest.raises(Exception, match="Status code: 403.*Forbidden"): + auth._handle_error(response) + + def test_handle_error_with_text_json_body_missing_error(jina_module: ModuleType) -> None: auth = jina_module.JinaAuth(_credentials(api_key="k")) response = MagicMock()