This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new 78dad35a29 [python][rest] Use HTTP status when error response omits
code (#10029)
78dad35a29 is described below
commit 78dad35a29f0ba5503143cbb8e9860aac8b58b0c
Author: Akash Reddy Jammula <[email protected]>
AuthorDate: Sun Sep 20 19:38:33 2026 -0700
[python][rest] Use HTTP status when error response omits code (#10029)
---
paimon-python/pypaimon/api/client.py | 7 +++-
paimon-python/pypaimon/tests/rest/client_test.py | 49 ++++++++++++++++++++++++
2 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/paimon-python/pypaimon/api/client.py
b/paimon-python/pypaimon/api/client.py
index 55730887ba..9e73c41723 100644
--- a/paimon-python/pypaimon/api/client.py
+++ b/paimon-python/pypaimon/api/client.py
@@ -246,9 +246,12 @@ def _parse_error_response(response_body: Optional[str],
status_code: int) -> Err
resource_type=error.resource_type if error and error.resource_type
else "",
resource_name=error.resource_name if error and error.resource_name
else "",
message=response_body if response_body else "response body is
null",
- code=error.code if error and error.code else status_code
+ code=error.code if error and error.code is not None else
status_code
)
-
+
+ if error.code is None:
+ error.code = status_code
+
return error
diff --git a/paimon-python/pypaimon/tests/rest/client_test.py
b/paimon-python/pypaimon/tests/rest/client_test.py
index 3a00310b4f..f064cca8c3 100644
--- a/paimon-python/pypaimon/tests/rest/client_test.py
+++ b/paimon-python/pypaimon/tests/rest/client_test.py
@@ -19,6 +19,8 @@ import unittest
from unittest import mock
from pypaimon.api.client import HttpClient, _parse_error_response
+from pypaimon.api.rest_exception import (AlreadyExistsException,
NoSuchResourceException,
+ ServiceUnavailableException)
class HttpClientTest(unittest.TestCase):
@@ -35,6 +37,26 @@ class HttpClientTest(unittest.TestCase):
self.assertEqual(error.resource_type, "table")
self.assertEqual(error.resource_name, "my_table")
+ def test_parse_error_response_uses_http_status_when_code_is_missing(self):
+ response_body = (
+ '{"message": "request failed", '
+ '"resourceType": "TABLE", "resourceName": "db.t"}'
+ )
+
+ for status_code in (404, 409, 503):
+ with self.subTest(status_code=status_code):
+ error = _parse_error_response(response_body, status_code)
+
+ self.assertEqual(error.message, "request failed")
+ self.assertEqual(error.code, status_code)
+ self.assertEqual(error.resource_type, "TABLE")
+ self.assertEqual(error.resource_name, "db.t")
+
+ def test_parse_error_response_preserves_explicit_zero_code(self):
+ error = _parse_error_response('{"message": "request failed", "code":
0}', 500)
+
+ self.assertEqual(error.code, 0)
+
def test_parse_error_response_with_unparsable_json(self):
# Test unparsable JSON with uppercase fields
response_body = '{"Message":"Your request is denied as lack of ssl
protect.","Code":"InvalidProtocol.NeedSsl"}'
@@ -59,6 +81,33 @@ class HttpClientTest(unittest.TestCase):
self.assertEqual(error.resource_type, '')
self.assertEqual(error.resource_name, '')
+ def test_execute_request_uses_http_status_for_typed_exception(self):
+ client = HttpClient("http://localhost:8080")
+ response_body = (
+ '{"message": "request failed", '
+ '"resourceType": "TABLE", "resourceName": "db.t"}'
+ )
+ cases = (
+ (404, NoSuchResourceException),
+ (409, AlreadyExistsException),
+ (503, ServiceUnavailableException),
+ )
+
+ for status_code, exception_type in cases:
+ with self.subTest(status_code=status_code):
+ response = mock.Mock(
+ ok=False,
+ status_code=status_code,
+ text=response_body,
+ headers={},
+ url="http://localhost:8080/test",
+ )
+ response.request.method = "GET"
+
+ with mock.patch.object(client.session, 'request',
return_value=response):
+ with self.assertRaises(exception_type):
+ client._execute_request("GET", response.url)
+
class HttpClientTimeoutTest(unittest.TestCase):
"""HttpClient passes its timeout to ``Session.request``.