This is an automated email from the ASF dual-hosted git repository. yuqi4733 pushed a commit to branch issue_10281 in repository https://gitbox.apache.org/repos/asf/gravitino.git
commit 26d82ba4394fa50f3a62ffce2772ebc298fd16cd Author: yuqi <[email protected]> AuthorDate: Fri Mar 6 16:10:02 2026 +0800 Fix: throw specific exceptions in MetadataObjectUtil.checkMetadataObject This change ensures that checking for the existence of metadata objects throws specific exceptions (e.g., NoSuchSchemaException, NoSuchTableException) instead of the generic NoSuchMetadataObjectException. This provides more accurate error reporting to clients. Fixes #10281. Co-authored-by: Copilot <[email protected]> --- .../apache/gravitino/utils/MetadataObjectUtil.java | 61 ++++++++++++++-------- .../server/web/rest/TestTableOperations.java | 37 +++++++++++++ 2 files changed, 77 insertions(+), 21 deletions(-) diff --git a/core/src/main/java/org/apache/gravitino/utils/MetadataObjectUtil.java b/core/src/main/java/org/apache/gravitino/utils/MetadataObjectUtil.java index 8b075bff1f..f3a47b3a39 100644 --- a/core/src/main/java/org/apache/gravitino/utils/MetadataObjectUtil.java +++ b/core/src/main/java/org/apache/gravitino/utils/MetadataObjectUtil.java @@ -18,8 +18,6 @@ */ package org.apache.gravitino.utils; -import static com.google.common.base.Preconditions.checkNotNull; - import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.collect.BiMap; @@ -33,12 +31,20 @@ import org.apache.gravitino.MetadataObject; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.authorization.AuthorizationUtils; import org.apache.gravitino.exceptions.IllegalMetadataObjectException; +import org.apache.gravitino.exceptions.NoSuchCatalogException; +import org.apache.gravitino.exceptions.NoSuchFilesetException; import org.apache.gravitino.exceptions.NoSuchJobException; import org.apache.gravitino.exceptions.NoSuchJobTemplateException; import org.apache.gravitino.exceptions.NoSuchMetadataObjectException; +import org.apache.gravitino.exceptions.NoSuchMetalakeException; +import org.apache.gravitino.exceptions.NoSuchModelException; import org.apache.gravitino.exceptions.NoSuchPolicyException; import org.apache.gravitino.exceptions.NoSuchRoleException; +import org.apache.gravitino.exceptions.NoSuchSchemaException; +import org.apache.gravitino.exceptions.NoSuchTableException; import org.apache.gravitino.exceptions.NoSuchTagException; +import org.apache.gravitino.exceptions.NoSuchTopicException; +import org.apache.gravitino.exceptions.NoSuchViewException; public class MetadataObjectUtil { @@ -151,59 +157,72 @@ public class MetadataObjectUtil { GravitinoEnv env = GravitinoEnv.getInstance(); NameIdentifier identifier = toEntityIdent(metalake, object); - Supplier<NoSuchMetadataObjectException> exceptionToThrowSupplier = - () -> - new NoSuchMetadataObjectException( - "Metadata object %s type %s doesn't exist", object.fullName(), object.type()); - switch (object.type()) { case METALAKE: if (!metalake.equals(object.name())) { throw new IllegalMetadataObjectException("The metalake object name must be %s", metalake); } NameIdentifierUtil.checkMetalake(identifier); - check(env.metalakeDispatcher().metalakeExists(identifier), exceptionToThrowSupplier); + check( + env.metalakeDispatcher().metalakeExists(identifier), + () -> new NoSuchMetalakeException("Metalake %s doesn't exist", object.fullName())); break; case CATALOG: NameIdentifierUtil.checkCatalog(identifier); - check(env.catalogDispatcher().catalogExists(identifier), exceptionToThrowSupplier); + check( + env.catalogDispatcher().catalogExists(identifier), + () -> new NoSuchCatalogException("Catalog %s doesn't exist", object.fullName())); break; case SCHEMA: NameIdentifierUtil.checkSchema(identifier); - check(env.schemaDispatcher().schemaExists(identifier), exceptionToThrowSupplier); + check( + env.schemaDispatcher().schemaExists(identifier), + () -> new NoSuchSchemaException("Schema %s doesn't exist", object.fullName())); break; case FILESET: NameIdentifierUtil.checkFileset(identifier); - check(env.filesetDispatcher().filesetExists(identifier), exceptionToThrowSupplier); + check( + env.filesetDispatcher().filesetExists(identifier), + () -> new NoSuchFilesetException("Fileset %s doesn't exist", object.fullName())); break; case TABLE: NameIdentifierUtil.checkTable(identifier); - check(env.tableDispatcher().tableExists(identifier), exceptionToThrowSupplier); + check( + env.tableDispatcher().tableExists(identifier), + () -> new NoSuchTableException("Table %s doesn't exist", object.fullName())); break; case COLUMN: NameIdentifierUtil.checkColumn(identifier); NameIdentifier tableIdent = NameIdentifier.of(identifier.namespace().levels()); - check(env.tableDispatcher().tableExists(tableIdent), exceptionToThrowSupplier); + check( + env.tableDispatcher().tableExists(tableIdent), + () -> new NoSuchTableException("Table %s doesn't exist", tableIdent.toString())); break; case TOPIC: NameIdentifierUtil.checkTopic(identifier); - check(env.topicDispatcher().topicExists(identifier), exceptionToThrowSupplier); + check( + env.topicDispatcher().topicExists(identifier), + () -> new NoSuchTopicException("Topic %s doesn't exist", object.fullName())); break; case MODEL: NameIdentifierUtil.checkModel(identifier); - check(env.modelDispatcher().modelExists(identifier), exceptionToThrowSupplier); + check( + env.modelDispatcher().modelExists(identifier), + () -> new NoSuchModelException("Model %s doesn't exist", object.fullName())); break; case VIEW: NameIdentifierUtil.checkView(identifier); - check(env.viewDispatcher().viewExists(identifier), exceptionToThrowSupplier); + check( + env.viewDispatcher().viewExists(identifier), + () -> new NoSuchViewException("View %s doesn't exist", object.fullName())); break; case ROLE: @@ -211,7 +230,7 @@ public class MetadataObjectUtil { try { env.accessControlDispatcher().getRole(metalake, object.fullName()); } catch (NoSuchRoleException nsr) { - throw exceptionToThrowSupplier.get(); + throw nsr; } break; @@ -220,7 +239,7 @@ public class MetadataObjectUtil { try { env.tagDispatcher().getTag(metalake, object.fullName()); } catch (NoSuchTagException nsr) { - throw exceptionToThrowSupplier.get(); + throw nsr; } break; @@ -229,7 +248,7 @@ public class MetadataObjectUtil { try { env.policyDispatcher().getPolicy(metalake, object.fullName()); } catch (NoSuchPolicyException nsr) { - throw checkNotNull(exceptionToThrowSupplier).get(); + throw nsr; } break; @@ -238,7 +257,7 @@ public class MetadataObjectUtil { try { env.jobOperationDispatcher().getJob(metalake, object.fullName()); } catch (NoSuchJobException e) { - throw exceptionToThrowSupplier.get(); + throw e; } break; @@ -247,7 +266,7 @@ public class MetadataObjectUtil { try { env.jobOperationDispatcher().getJobTemplate(metalake, object.fullName()); } catch (NoSuchJobTemplateException e) { - throw exceptionToThrowSupplier.get(); + throw e; } break; diff --git a/server/src/test/java/org/apache/gravitino/server/web/rest/TestTableOperations.java b/server/src/test/java/org/apache/gravitino/server/web/rest/TestTableOperations.java index 4e2da1e8cb..cbe9f3de7c 100644 --- a/server/src/test/java/org/apache/gravitino/server/web/rest/TestTableOperations.java +++ b/server/src/test/java/org/apache/gravitino/server/web/rest/TestTableOperations.java @@ -994,4 +994,41 @@ public class TestTableOperations extends BaseOperationsTest { return table; } + + @Test + public void testCreateTableWithNonExistentSchema() { + String nonExistentSchema = "non_existent_schema"; + NameIdentifier schemaIdent = NameIdentifier.of(metalake, catalog, nonExistentSchema); + + // Mock schema not exists + when(schemaDispatcher.schemaExists(schemaIdent)).thenReturn(false); + + TableCreateRequest req = + new TableCreateRequest( + "table1", + "comment", + new ColumnDTO[] { + new ColumnDTO.Builder() + .withName("col1") + .withDataType(Types.IntegerType.get()) + .withComment("col_comment") + .build() + }, + ImmutableMap.of(), + new SortOrderDTO[0], + null, + new Partitioning[0], + new IndexDTO[0]); + + Response resp = + target(tablePath(metalake, catalog, nonExistentSchema)) + .request(MediaType.APPLICATION_JSON_TYPE) + .accept("application/vnd.gravitino.v1+json") + .post(Entity.entity(req, MediaType.APPLICATION_JSON_TYPE)); + + Assertions.assertEquals(Response.Status.NOT_FOUND.getStatusCode(), resp.getStatus()); + + ErrorResponse errorResp = resp.readEntity(ErrorResponse.class); + Assertions.assertEquals(NoSuchSchemaException.class.getSimpleName(), errorResp.getType()); + } }
