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");
+ }
+ }
}