This is an automated email from the ASF dual-hosted git repository.

lzljs3620320 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 c6dc3aaaca [core] Improve HttpClient error response handling (#7254)
c6dc3aaaca is described below

commit c6dc3aaacaf93bf707c8721e50ba640176c6b245
Author: Jiajia Li <[email protected]>
AuthorDate: Wed Feb 11 09:03:00 2026 +0800

    [core] Improve HttpClient error response handling (#7254)
    
    This PR improves error response handling in HttpClient by ensuring that
    error messages are always populated with meaningful information when the
    response body is available.
---
 .../java/org/apache/paimon/rest/HttpClient.java    | 31 +++++++++++++-----
 .../org/apache/paimon/rest/HttpClientTest.java     | 38 ++++++++++++++++++++++
 2 files changed, 60 insertions(+), 9 deletions(-)

diff --git a/paimon-api/src/main/java/org/apache/paimon/rest/HttpClient.java 
b/paimon-api/src/main/java/org/apache/paimon/rest/HttpClient.java
index 84ddb6c75e..5b3c481c12 100644
--- a/paimon-api/src/main/java/org/apache/paimon/rest/HttpClient.java
+++ b/paimon-api/src/main/java/org/apache/paimon/rest/HttpClient.java
@@ -131,19 +131,14 @@ public class HttpClient implements RESTClient {
                     response -> {
                         String responseBodyStr = 
RESTUtil.extractResponseBodyAsString(response);
                         if (!RESTUtil.isSuccessful(response)) {
-                            ErrorResponse error;
+                            ErrorResponse error = null;
                             try {
                                 error = RESTApi.fromJson(responseBodyStr, 
ErrorResponse.class);
                             } catch (JsonProcessingException e) {
-                                error =
-                                        new ErrorResponse(
-                                                null,
-                                                null,
-                                                responseBodyStr != null
-                                                        ? responseBodyStr
-                                                        : "response body is 
null",
-                                                response.getCode());
+                                // ignore exception
                             }
+                            error = buildErrorResponse(error, responseBodyStr, 
response.getCode());
+
                             errorHandler.accept(error, 
extractRequestId(response));
                         }
                         if (responseType != null && responseBodyStr != null) {
@@ -228,4 +223,22 @@ public class HttpClient implements RESTClient {
                 .map(entry -> new BasicHeader(entry.getKey(), 
entry.getValue()))
                 .toArray(Header[]::new);
     }
+
+    private static ErrorResponse buildErrorResponse(
+            ErrorResponse error, String responseBodyStr, int errorCode) {
+        if (error == null || error.getMessage() == null || 
error.getMessage().isEmpty()) {
+            String resourceType =
+                    (error != null && error.getResourceType() != null)
+                            ? error.getResourceType()
+                            : "";
+            String resourceName =
+                    (error != null && error.getResourceName() != null)
+                            ? error.getResourceName()
+                            : "";
+            String message = responseBodyStr != null ? responseBodyStr : 
"response body is null";
+            int code = (error != null && error.getCode() != null) ? 
error.getCode() : errorCode;
+            error = new ErrorResponse(resourceType, resourceName, message, 
code);
+        }
+        return error;
+    }
 }
diff --git 
a/paimon-core/src/test/java/org/apache/paimon/rest/HttpClientTest.java 
b/paimon-core/src/test/java/org/apache/paimon/rest/HttpClientTest.java
index 370da8b63f..6cf9f44802 100644
--- a/paimon-core/src/test/java/org/apache/paimon/rest/HttpClientTest.java
+++ b/paimon-core/src/test/java/org/apache/paimon/rest/HttpClientTest.java
@@ -223,4 +223,42 @@ public class HttpClientTest {
                                         ));
         return parameters;
     }
+
+    @Test
+    public void testGetWithUnparsableJsonErrorResponse() {
+        // Test case for JSON response with mismatched field names that cannot 
be parsed as
+        // ErrorResponse
+        String jsonWithUppercaseFields =
+                "{\"Message\":\"Your request is denied as lack of ssl 
protect.\","
+                        + "\"Code\":\"InvalidProtocol.NeedSsl\"}";
+        server.enqueueResponse(jsonWithUppercaseFields, 403);
+
+        try {
+            httpClient.get(MOCK_PATH, MockRESTData.class, restAuthFunction);
+            Assertions.fail("Expected exception to be thrown");
+        } catch (Exception e) {
+            Assertions.assertTrue(
+                    e.getMessage().contains("Your request is denied as lack of 
ssl protect")
+                            || 
e.getMessage().contains(jsonWithUppercaseFields),
+                    "Error message should contain the original response body");
+        }
+    }
+
+    @Test
+    public void testPostWithNonJsonErrorResponse() {
+        // Test case for non-JSON response (plain text) that cannot be parsed
+        String plainTextResponse = "Internal Server Error: Database connection 
failed";
+        server.enqueueResponse(plainTextResponse, 500);
+
+        try {
+            httpClient.post(MOCK_PATH, mockResponseData, MockRESTData.class, 
restAuthFunction);
+            Assertions.fail("Expected exception to be thrown");
+        } catch (Exception e) {
+            // Verify that the error message contains the original plain text 
response
+            Assertions.assertTrue(
+                    e.getMessage().contains(plainTextResponse)
+                            || e.getMessage().contains("Database connection 
failed"),
+                    "Error message should contain the original non-JSON 
response");
+        }
+    }
 }

Reply via email to