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

jerryshao pushed a commit to branch branch-1.3
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/branch-1.3 by this push:
     new 2bea1955a4 [Cherry-pick to branch-1.3] Trino Gravitino connector 
throws NullPointerException #11365 (#11426) (#11562)
2bea1955a4 is described below

commit 2bea1955a49ce0a0357502900b22ca167582b113
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed Jun 10 18:13:33 2026 -0700

    [Cherry-pick to branch-1.3] Trino Gravitino connector throws 
NullPointerException #11365 (#11426) (#11562)
    
    **Cherry-pick Information:**
    - Original commit: 732adb185b1e5173cc99fb5e9fa07f5da35cf694
    - Target branch: `branch-1.3`
    - Status: ✅ Clean cherry-pick (no conflicts)
    
    Co-authored-by: Octavio Herrera Contreras 
<[email protected]>
    Co-authored-by: yuhui <[email protected]>
---
 .../org/apache/gravitino/client/HTTPClient.java    | 35 ++++++++++++--
 .../apache/gravitino/client/TestHTTPClient.java    | 53 ++++++++++++++++++++++
 2 files changed, 84 insertions(+), 4 deletions(-)

diff --git 
a/clients/client-java/src/main/java/org/apache/gravitino/client/HTTPClient.java 
b/clients/client-java/src/main/java/org/apache/gravitino/client/HTTPClient.java
index b5de221c11..2862ac9e7c 100644
--- 
a/clients/client-java/src/main/java/org/apache/gravitino/client/HTTPClient.java
+++ 
b/clients/client-java/src/main/java/org/apache/gravitino/client/HTTPClient.java
@@ -26,8 +26,10 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;
 import java.io.IOException;
 import java.io.UncheckedIOException;
+import java.net.ConnectException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.net.UnknownHostException;
 import java.nio.charset.StandardCharsets;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
@@ -258,10 +260,18 @@ public class HTTPClient implements RESTClient {
       if (params != null) {
         params.forEach(builder::addParameter);
       }
-      return builder.build();
+
+      URI requestUri = builder.build();
+
+      if (requestUri.getScheme() == null || requestUri.getHost() == null) {
+        throw new RESTException(
+            "Invalid request URI built from base URI %s and path %s: %s", uri, 
path, requestUri);
+      }
+
+      return requestUri;
     } catch (URISyntaxException e) {
       throw new RESTException(
-          "Failed to create request URI from base %s, params %s", baseUri, 
params);
+          e, "Failed to create request URI from base %s, path %s, params %s", 
uri, path, params);
     }
   }
 
@@ -347,7 +357,8 @@ public class HTTPClient implements RESTClient {
           "Received a malformed path for a REST request: %s. Paths should not 
start with /", path);
     }
 
-    HttpUriRequestBase request = new HttpUriRequestBase(method.name(), 
buildUri(path, queryParams));
+    URI requestUri = buildUri(path, queryParams);
+    HttpUriRequestBase request = new HttpUriRequestBase(method.name(), 
requestUri);
 
     if (requestBody instanceof Map) {
       // encode maps as form data, application/x-www-form-urlencoded
@@ -406,8 +417,24 @@ public class HTTPClient implements RESTClient {
             response.getCode(),
             responseType != null ? responseType.getSimpleName() : "unknown");
       }
+    } catch (UnknownHostException e) {
+      throw new RESTException(
+          e,
+          "Cannot resolve Gravitino server host while processing %s request: 
%s",
+          method,
+          requestUri);
+    } catch (ConnectException e) {
+      throw new RESTException(
+          e,
+          "Failed to connect to Gravitino server while processing %s request: 
%s",
+          method,
+          requestUri);
     } catch (IOException e) {
-      throw new RESTException(e, "Error occurred while processing %s request", 
method);
+      throw new RESTException(
+          e,
+          "Failed to execute request to Gravitino server while processing %s 
request: %s",
+          method,
+          requestUri);
     }
   }
 
diff --git 
a/clients/client-java/src/test/java/org/apache/gravitino/client/TestHTTPClient.java
 
b/clients/client-java/src/test/java/org/apache/gravitino/client/TestHTTPClient.java
index 64b270bc91..62fb95accb 100644
--- 
a/clients/client-java/src/test/java/org/apache/gravitino/client/TestHTTPClient.java
+++ 
b/clients/client-java/src/test/java/org/apache/gravitino/client/TestHTTPClient.java
@@ -33,12 +33,14 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.ImmutableMap;
 import java.io.IOException;
 import java.net.SocketTimeoutException;
+import java.util.Collections;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 import org.apache.gravitino.dto.responses.ErrorResponse;
+import org.apache.gravitino.dto.responses.MetalakeResponse;
 import org.apache.gravitino.exceptions.NotFoundException;
 import org.apache.gravitino.exceptions.RESTException;
 import org.apache.gravitino.rest.RESTRequest;
@@ -353,6 +355,57 @@ public class TestHTTPClient {
     }
   }
 
+  @Test
+  public void testConnectionRefusedThrowsMeaningfulException() {
+    GravitinoAdminClient client = 
GravitinoAdminClient.builder("http://localhost:1";).build();
+
+    RESTException exception =
+        Assertions.assertThrows(RESTException.class, () -> 
client.listMetalakes());
+
+    Assertions.assertTrue(
+        exception.getMessage().contains("Failed to connect to Gravitino 
server"),
+        exception.getMessage());
+
+    Assertions.assertTrue(exception.getMessage().contains("localhost"), 
exception.getMessage());
+  }
+
+  @Test
+  public void testUnresolvableHostThrowsMeaningfulException() {
+    GravitinoAdminClient client =
+        
GravitinoAdminClient.builder("http://bad-host-that-does-not-exist.invalid:9090";).build();
+
+    RESTException exception =
+        Assertions.assertThrows(RESTException.class, () -> 
client.listMetalakes());
+
+    Assertions.assertTrue(
+        exception.getMessage().contains("Cannot resolve Gravitino server 
host"),
+        exception.getMessage());
+
+    Assertions.assertTrue(
+        
exception.getMessage().contains("bad-host-that-does-not-exist.invalid"),
+        exception.getMessage());
+  }
+
+  @Test
+  public void testInvalidBaseUriFailsBeforeHttpClientExecute() {
+    HTTPClient client = 
HTTPClient.builder(Collections.emptyMap()).uri("http://";).build();
+
+    RESTException exception =
+        Assertions.assertThrows(
+            RESTException.class,
+            () ->
+                client.get(
+                    "api/metalakes/test",
+                    MetalakeResponse.class,
+                    Collections.emptyMap(),
+                    ErrorHandlers.metalakeErrorHandler()));
+
+    Assertions.assertTrue(
+        exception.getMessage().contains("Failed to create request URI")
+            || exception.getMessage().contains("Invalid Gravitino server URI"),
+        "Unexpected exception message: " + exception.getMessage());
+  }
+
   public static void testHttpMethodOnSuccess(
       Method method, boolean hasRequestBody, boolean hasResponseBody)
       throws JsonProcessingException {

Reply via email to