This is an automated email from the ASF dual-hosted git repository.
jmclean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 8956eaf195 [#10123] Fix NPE in createMetalake REST handler (#10158)
8956eaf195 is described below
commit 8956eaf19545cf0609378533f3567d23b9e5e0fa
Author: Chujiang <[email protected]>
AuthorDate: Wed Mar 4 08:04:03 2026 +0800
[#10123] Fix NPE in createMetalake REST handler (#10158)
## What this PR does
Fixes #10123
The `createMetalake` REST handler can crash with a
`NullPointerException` when the request body is missing or deserializes
to null. The issue was that:
1. The handler logs `request.getName()` before validation - if `request`
is null, this throws NPE
2. The exception handler also calls `request.getName()` - if `request`
is null, this throws another NPE
3. This results in an internal server error instead of a proper client
error response
## Changes
- **MetalakeOperations.java**: Added explicit null check for request at
the start of `createMetalake()` method
- **MetalakeOperations.java**: Safely retrieves metalake name in
exception handler using ternary operator
- **TestMetalakeOperations.java**: Added new test
`testCreateMetalakeWithNullRequest()` to verify null request handling
## Behavior
- When request is null, the endpoint now returns a proper `BAD_REQUEST`
response with clear error message
- No NPE is thrown during request processing or exception handling
- Error message clearly states "Request body cannot be null"
## Testing
Added unit test `testCreateMetalakeWithNullRequest()` that verifies:
- Null request returns BAD_REQUEST status code (not
INTERNAL_SERVER_ERROR)
- Error response has correct error code (ILLEGAL_ARGUMENTS)
- Error response has correct type (IllegalArgumentException)
- Error message contains "Request body cannot be null"
---
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
---
.../gravitino/server/web/rest/MetalakeOperations.java | 9 ++++++++-
.../server/web/rest/TestMetalakeOperations.java | 19 +++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git
a/server/src/main/java/org/apache/gravitino/server/web/rest/MetalakeOperations.java
b/server/src/main/java/org/apache/gravitino/server/web/rest/MetalakeOperations.java
index 8b4e20934b..4424d6b133 100644
---
a/server/src/main/java/org/apache/gravitino/server/web/rest/MetalakeOperations.java
+++
b/server/src/main/java/org/apache/gravitino/server/web/rest/MetalakeOperations.java
@@ -117,6 +117,12 @@ public class MetalakeOperations {
"Only service admins can create metalakes, current user can't create
the metalake,"
+ " you should configure it in the server configuration first")
public Response createMetalake(MetalakeCreateRequest request) {
+ if (request == null) {
+ LOG.warn("Received create metalake request with null request body");
+ return ExceptionHandlers.handleMetalakeException(
+ OperationType.CREATE, "", new IllegalArgumentException("Request body
cannot be null"));
+ }
+
LOG.info("Received create metalake request for {}", request.getName());
try {
return Utils.doAs(
@@ -133,7 +139,8 @@ public class MetalakeOperations {
});
} catch (Exception e) {
- return ExceptionHandlers.handleMetalakeException(OperationType.CREATE,
request.getName(), e);
+ String metalakeName = request != null ? request.getName() : "";
+ return ExceptionHandlers.handleMetalakeException(OperationType.CREATE,
metalakeName, e);
}
}
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/rest/TestMetalakeOperations.java
b/server/src/test/java/org/apache/gravitino/server/web/rest/TestMetalakeOperations.java
index 895b4fd492..0cbf2594c8 100644
---
a/server/src/test/java/org/apache/gravitino/server/web/rest/TestMetalakeOperations.java
+++
b/server/src/test/java/org/apache/gravitino/server/web/rest/TestMetalakeOperations.java
@@ -233,6 +233,25 @@ public class TestMetalakeOperations extends
BaseOperationsTest {
IllegalArgumentException.class.getSimpleName(),
errorResponse.getType());
}
+ @Test
+ public void testCreateMetalakeWithNullRequest() {
+ // Test with null request body - should not throw NPE
+ Response resp =
+ target("/metalakes")
+ .request(MediaType.APPLICATION_JSON_TYPE)
+ .accept("application/vnd.gravitino.v1+json")
+ .post(Entity.entity(null, MediaType.APPLICATION_JSON_TYPE));
+
+ // Should return BAD_REQUEST instead of INTERNAL_SERVER_ERROR from NPE
+ Assertions.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(),
resp.getStatus());
+
+ ErrorResponse errorResponse = resp.readEntity(ErrorResponse.class);
+ Assertions.assertEquals(ErrorConstants.ILLEGAL_ARGUMENTS_CODE,
errorResponse.getCode());
+ Assertions.assertEquals(
+ IllegalArgumentException.class.getSimpleName(),
errorResponse.getType());
+ Assertions.assertTrue(errorResponse.getMessage().contains("Request body
cannot be null"));
+ }
+
@Test
public void testLoadMetalake() {
String metalakeName = "test";