This is an automated email from the ASF dual-hosted git repository.
snazy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git
The following commit(s) were added to refs/heads/main by this push:
new a846588fa Unify exception construction in utility class (#3842)
a846588fa is described below
commit a846588fa236e4f077a70ed5625336497468aeeb
Author: Robert Stupp <[email protected]>
AuthorDate: Tue Feb 24 08:39:36 2026 +0100
Unify exception construction in utility class (#3842)
There are many places that construct `NoSuchNamespaceException`s and
`NotFoundException`s. This change unifies this in common utility functions.
No functional changes.
---
.../polaris/service/admin/PolarisAdminService.java | 16 ++--
.../service/catalog/common/CatalogHandler.java | 63 +++----------
.../service/catalog/common/ExceptionUtils.java | 102 +++++++++++++++++++++
.../generic/PolarisGenericTableCatalog.java | 34 ++++---
.../catalog/iceberg/CatalogHandlerUtils.java | 16 ++--
.../service/catalog/iceberg/IcebergCatalog.java | 71 +++++++-------
.../catalog/iceberg/IcebergCatalogHandler.java | 14 ++-
.../service/catalog/policy/PolicyCatalog.java | 9 +-
.../catalog/policy/PolicyCatalogHandler.java | 6 +-
.../service/catalog/policy/PolicyCatalogUtils.java | 10 +-
10 files changed, 204 insertions(+), 137 deletions(-)
diff --git
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java
index 158146868..b47f4790a 100644
---
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java
+++
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java
@@ -20,6 +20,8 @@ package org.apache.polaris.service.admin;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.noSuchNamespaceException;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.notFoundExceptionForTableLikeEntity;
import com.google.common.base.Strings;
import jakarta.annotation.Nonnull;
@@ -42,7 +44,6 @@ import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.catalog.TableIdentifier;
import org.apache.iceberg.exceptions.AlreadyExistsException;
import org.apache.iceberg.exceptions.BadRequestException;
-import org.apache.iceberg.exceptions.NoSuchNamespaceException;
import org.apache.iceberg.exceptions.NotFoundException;
import org.apache.iceberg.exceptions.ValidationException;
import org.apache.polaris.core.PolarisCallContext;
@@ -121,7 +122,6 @@ import
org.apache.polaris.core.storage.PolarisStorageConfigurationInfo;
import org.apache.polaris.core.storage.StorageLocation;
import org.apache.polaris.core.storage.aws.AwsStorageConfigurationInfo;
import org.apache.polaris.core.storage.azure.AzureStorageConfigurationInfo;
-import org.apache.polaris.service.catalog.common.CatalogHandler;
import org.apache.polaris.service.config.ReservedProperties;
import org.apache.polaris.service.types.PolicyIdentifier;
import org.slf4j.Logger;
@@ -462,8 +462,8 @@ public class PolarisAdminService {
throw new NotFoundException("Catalog not found: %s", catalogName);
} else if (status.getStatus() ==
ResolverStatus.StatusEnum.PATH_COULD_NOT_BE_FULLY_RESOLVED) {
if (status.getFailedToResolvePath().lastEntityType() ==
PolarisEntityType.NAMESPACE) {
- throw new NoSuchNamespaceException(
- "Namespace does not exist: %s",
status.getFailedToResolvePath().entityNames());
+ throw noSuchNamespaceException(
+
Namespace.of(status.getFailedToResolvePath().entityNames().toArray(new
String[0])));
} else {
throw new NotFoundException("CatalogRole not found: %s.%s",
catalogName, catalogRoleName);
}
@@ -507,7 +507,7 @@ public class PolarisAdminService {
throw new NotFoundException("Catalog not found: %s", catalogName);
} else if (status.getStatus() ==
ResolverStatus.StatusEnum.PATH_COULD_NOT_BE_FULLY_RESOLVED) {
if (status.getFailedToResolvePath().lastEntityType() ==
PolarisEntityType.TABLE_LIKE) {
- CatalogHandler.throwNotFoundExceptionForTableLikeEntity(identifier,
subTypes);
+ throw notFoundExceptionForTableLikeEntity(identifier, subTypes);
} else {
throw new NotFoundException("CatalogRole not found: %s.%s",
catalogName, catalogRoleName);
}
@@ -522,7 +522,7 @@ public class PolarisAdminService {
FeatureConfiguration.ENABLE_SUB_CATALOG_RBAC_FOR_FEDERATED_CATALOGS,
catalogEntity);
if (!(resolutionManifest.getIsPassthroughFacade() &&
rbacForFederatedCatalogsEnabled)
&&
!subTypes.contains(tableLikeWrapper.getRawLeafEntity().getSubType())) {
- CatalogHandler.throwNotFoundExceptionForTableLikeEntity(identifier,
subTypes);
+ throw notFoundExceptionForTableLikeEntity(identifier, subTypes);
}
PolarisResolvedPathWrapper catalogRoleWrapper =
@@ -2150,7 +2150,7 @@ public class PolarisAdminService {
identifier.name(), catalogEntity.getName()));
}
} else {
- CatalogHandler.throwNotFoundExceptionForTableLikeEntity(identifier,
subTypes);
+ throw notFoundExceptionForTableLikeEntity(identifier, subTypes);
}
}
List<PolarisEntity> catalogPath = resolvedPathWrapper.getRawParentPath();
@@ -2255,7 +2255,7 @@ public class PolarisAdminService {
identifier, PolarisEntityType.TABLE_LIKE,
PolarisEntitySubType.ANY_SUBTYPE);
if (resolvedPathWrapper == null
||
!subTypes.contains(resolvedPathWrapper.getRawLeafEntity().getSubType())) {
- CatalogHandler.throwNotFoundExceptionForTableLikeEntity(identifier,
subTypes);
+ throw notFoundExceptionForTableLikeEntity(identifier, subTypes);
}
PolarisEntity tableLikeEntity = resolvedPathWrapper.getRawLeafEntity();
diff --git
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/common/CatalogHandler.java
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/common/CatalogHandler.java
index 0b4f08a1c..b6fba5c85 100644
---
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/common/CatalogHandler.java
+++
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/common/CatalogHandler.java
@@ -18,7 +18,9 @@
*/
package org.apache.polaris.service.catalog.common;
-import static
org.apache.polaris.core.entity.PolarisEntitySubType.ICEBERG_TABLE;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.entityNameForSubType;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.noSuchNamespaceException;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.notFoundExceptionForTableLikeEntity;
import java.util.Arrays;
import java.util.EnumSet;
@@ -27,9 +29,6 @@ import java.util.Optional;
import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.catalog.TableIdentifier;
import org.apache.iceberg.exceptions.AlreadyExistsException;
-import org.apache.iceberg.exceptions.NoSuchNamespaceException;
-import org.apache.iceberg.exceptions.NoSuchTableException;
-import org.apache.iceberg.exceptions.NoSuchViewException;
import org.apache.polaris.core.auth.PolarisAuthorizableOperation;
import org.apache.polaris.core.auth.PolarisAuthorizer;
import org.apache.polaris.core.auth.PolarisPrincipal;
@@ -137,7 +136,7 @@ public abstract class CatalogHandler {
resolutionManifest.resolveAll();
PolarisResolvedPathWrapper target =
resolutionManifest.getResolvedPath(namespace, true);
if (target == null) {
- throw new NoSuchNamespaceException("Namespace does not exist: %s",
namespace);
+ throw noSuchNamespaceException(namespace);
}
authorizer()
.authorizeOrThrow(
@@ -170,7 +169,7 @@ public abstract class CatalogHandler {
resolutionManifest.resolveAll();
PolarisResolvedPathWrapper target =
resolutionManifest.getResolvedPath(parentNamespace, true);
if (target == null) {
- throw new NoSuchNamespaceException("Namespace does not exist: %s",
parentNamespace);
+ throw noSuchNamespaceException(parentNamespace);
}
authorizer()
.authorizeOrThrow(
@@ -207,7 +206,7 @@ public abstract class CatalogHandler {
resolutionManifest.resolveAll();
PolarisResolvedPathWrapper target =
resolutionManifest.getResolvedPath(namespace, true);
if (target == null) {
- throw new NoSuchNamespaceException("Namespace does not exist: %s",
namespace);
+ throw noSuchNamespaceException(namespace);
}
authorizer()
.authorizeOrThrow(
@@ -253,7 +252,7 @@ public abstract class CatalogHandler {
PolarisResolvedPathWrapper target =
resolutionManifest.getResolvedPath(identifier,
PolarisEntityType.TABLE_LIKE, subType, true);
if (target == null) {
- throwNotFoundExceptionForTableLikeEntity(identifier, List.of(subType));
+ throw notFoundExceptionForTableLikeEntity(identifier, subType);
}
for (PolarisAuthorizableOperation op : ops) {
@@ -290,7 +289,7 @@ public abstract class CatalogHandler {
TableIdentifier identifier =
PolarisCatalogHelpers.listToTableIdentifier(
status.getFailedToResolvePath().entityNames());
- throwNotFoundExceptionForTableLikeEntity(identifier, List.of(subType));
+ throw notFoundExceptionForTableLikeEntity(identifier, subType);
}
List<PolarisResolvedPathWrapper> targets =
@@ -301,12 +300,7 @@ public abstract class CatalogHandler {
resolutionManifest.getResolvedPath(
identifier, PolarisEntityType.TABLE_LIKE,
subType, true))
.orElseThrow(
- () ->
- subType == ICEBERG_TABLE
- ? new NoSuchTableException(
- "Table does not exist: %s", identifier)
- : new NoSuchViewException(
- "View does not exist: %s",
identifier)))
+ () ->
notFoundExceptionForTableLikeEntity(identifier, subType)))
.toList();
authorizer()
.authorizeOrThrow(
@@ -342,10 +336,10 @@ public abstract class CatalogHandler {
ResolverStatus status = resolutionManifest.resolveAll();
if (status.getStatus() ==
ResolverStatus.StatusEnum.PATH_COULD_NOT_BE_FULLY_RESOLVED
&& status.getFailedToResolvePath().lastEntityType() ==
PolarisEntityType.NAMESPACE) {
- throw new NoSuchNamespaceException("Namespace does not exist: %s",
dst.namespace());
+ throw noSuchNamespaceException(dst.namespace());
} else if (resolutionManifest.getResolvedPath(src,
PolarisEntityType.TABLE_LIKE, subType)
== null) {
- throwNotFoundExceptionForTableLikeEntity(dst, List.of(subType));
+ throw notFoundExceptionForTableLikeEntity(dst, subType);
}
// Normally, since we added the dst as an optional path, we'd expect it to
only get resolved
@@ -359,14 +353,11 @@ public abstract class CatalogHandler {
switch (dstLeafSubType) {
case ICEBERG_TABLE:
- throw new AlreadyExistsException("Cannot rename %s to %s. Table
already exists", src, dst);
-
case PolarisEntitySubType.ICEBERG_VIEW:
- throw new AlreadyExistsException("Cannot rename %s to %s. View already
exists", src, dst);
-
case PolarisEntitySubType.GENERIC_TABLE:
throw new AlreadyExistsException(
- "Cannot rename %s to %s. Generic table already exists", src, dst);
+ "Cannot rename %s to %s. %s already exists",
+ src, dst, entityNameForSubType(dstLeafSubType));
default:
break;
@@ -386,32 +377,4 @@ public abstract class CatalogHandler {
initializeCatalog();
}
-
- /**
- * Helper function for when a TABLE_LIKE entity is not found so we want to
throw the appropriate
- * exception. Used in Iceberg APIs, so the Iceberg messages cannot be
changed.
- *
- * @param subTypes The subtypes of the entity that the exception should
report doesn't exist
- */
- public static void throwNotFoundExceptionForTableLikeEntity(
- TableIdentifier identifier, List<PolarisEntitySubType> subTypes) {
-
- // In this case, we assume it's a table
- if (subTypes.size() > 1) {
- throw new NoSuchTableException("Table does not exist: %s", identifier);
- } else {
- PolarisEntitySubType subType = subTypes.getFirst();
- switch (subType) {
- case ICEBERG_TABLE:
- throw new NoSuchTableException("Table does not exist: %s",
identifier);
- case ICEBERG_VIEW:
- throw new NoSuchViewException("View does not exist: %s", identifier);
- case GENERIC_TABLE:
- throw new NoSuchTableException("Generic table does not exist: %s",
identifier);
- default:
- // Assume it's a table
- throw new NoSuchTableException("Table does not exist: %s",
identifier);
- }
- }
- }
}
diff --git
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/common/ExceptionUtils.java
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/common/ExceptionUtils.java
new file mode 100644
index 000000000..1e8a586cf
--- /dev/null
+++
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/common/ExceptionUtils.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.polaris.service.catalog.common;
+
+import java.util.List;
+import org.apache.iceberg.catalog.Namespace;
+import org.apache.iceberg.catalog.TableIdentifier;
+import org.apache.iceberg.exceptions.AlreadyExistsException;
+import org.apache.iceberg.exceptions.NoSuchNamespaceException;
+import org.apache.iceberg.exceptions.NoSuchTableException;
+import org.apache.iceberg.exceptions.NoSuchViewException;
+import org.apache.polaris.core.entity.PolarisEntitySubType;
+
+public class ExceptionUtils {
+ private ExceptionUtils() {}
+
+ /**
+ * Helper function for when a TABLE_LIKE entity is not found, so we want to
throw the appropriate
+ * exception. Used in Iceberg APIs, so the Iceberg messages cannot be
changed.
+ *
+ * @param subTypes The subtypes of the entity that the exception should
report as non-existing
+ */
+ public static RuntimeException notFoundExceptionForTableLikeEntity(
+ TableIdentifier identifier, List<PolarisEntitySubType> subTypes) {
+
+ // In this case, we assume it's a table
+ if (subTypes.size() > 1) {
+ return new NoSuchTableException("Table does not exist: %s", identifier);
+ } else {
+ return notFoundExceptionForTableLikeEntity(identifier,
subTypes.getFirst());
+ }
+ }
+
+ public static RuntimeException notFoundExceptionForTableLikeEntity(
+ TableIdentifier identifier, PolarisEntitySubType subType) {
+ return notFoundExceptionForTableLikeEntity(identifier.toString(), subType);
+ }
+
+ public static RuntimeException notFoundExceptionForTableLikeEntity(
+ String identifier, PolarisEntitySubType subType) {
+ return subType == PolarisEntitySubType.ICEBERG_VIEW
+ ? new NoSuchViewException(
+ "%s does not exist: %s", entityNameForSubType(subType), identifier)
+ : new NoSuchTableException(
+ "%s does not exist: %s", entityNameForSubType(subType),
identifier);
+ }
+
+ public static RuntimeException alreadyExistsExceptionForTableLikeEntity(
+ TableIdentifier identifier, PolarisEntitySubType subType) {
+ return alreadyExistsExceptionForTableLikeEntity(identifier.toString(),
subType);
+ }
+
+ public static RuntimeException alreadyExistsExceptionForTableLikeEntity(
+ String identifier, PolarisEntitySubType subType) {
+ return new AlreadyExistsException(
+ "%s already exists: %s", entityNameForSubType(subType), identifier);
+ }
+
+ public static RuntimeException
alreadyExistsExceptionWithSameNameForTableLikeEntity(
+ TableIdentifier identifier, PolarisEntitySubType subType) {
+ return new AlreadyExistsException(
+ "%s with same name already exists: %s", entityNameForSubType(subType),
identifier);
+ }
+
+ public static String entityNameForSubType(PolarisEntitySubType subType) {
+ if (subType == null) {
+ return "Object";
+ }
+ return switch (subType) {
+ case ICEBERG_VIEW -> "View";
+ case GENERIC_TABLE -> "Generic table";
+ default -> "Table";
+ };
+ }
+
+ public static NoSuchNamespaceException
noSuchNamespaceException(TableIdentifier identifier) {
+ return noSuchNamespaceException(identifier.namespace());
+ }
+
+ public static NoSuchNamespaceException noSuchNamespaceException(Namespace
namespace) {
+ // tests assert this
+ var ns = namespace.isEmpty() ? "''" : namespace.toString();
+ return new NoSuchNamespaceException("Namespace does not exist: %s", ns);
+ }
+}
diff --git
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java
index b776788be..a1c6078f4 100644
---
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java
+++
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java
@@ -19,14 +19,14 @@
package org.apache.polaris.service.catalog.generic;
import static java.util.Objects.requireNonNull;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.alreadyExistsExceptionForTableLikeEntity;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.noSuchNamespaceException;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.notFoundExceptionForTableLikeEntity;
import java.util.List;
import java.util.Map;
import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.catalog.TableIdentifier;
-import org.apache.iceberg.exceptions.AlreadyExistsException;
-import org.apache.iceberg.exceptions.NoSuchNamespaceException;
-import org.apache.iceberg.exceptions.NoSuchTableException;
import org.apache.polaris.core.catalog.GenericTableCatalog;
import org.apache.polaris.core.catalog.PolarisCatalogHelpers;
import org.apache.polaris.core.context.CallContext;
@@ -109,8 +109,7 @@ public class PolarisGenericTableCatalog implements
GenericTableCatalog {
.setCreateTimestamp(System.currentTimeMillis())
.build();
} else {
- throw new AlreadyExistsException(
- "Iceberg table, view, or generic table already exists: %s",
tableIdentifier);
+ throw alreadyExistsExceptionForTableLikeEntity(tableIdentifier,
entity.getSubType());
}
EntityResult res =
@@ -119,17 +118,14 @@ public class PolarisGenericTableCatalog implements
GenericTableCatalog {
PolarisEntity.toCoreList(catalogPath),
entity);
if (!res.isSuccess()) {
- switch (res.getReturnStatus()) {
- case BaseResult.ReturnStatus.ENTITY_ALREADY_EXISTS:
- throw new AlreadyExistsException(
- "Iceberg table, view, or generic table already exists: %s",
tableIdentifier);
-
- default:
- throw new IllegalStateException(
- String.format(
- "Unknown error status for identifier %s: %s with extraInfo:
%s",
- tableIdentifier, res.getReturnStatus(),
res.getExtraInformation()));
+ if (requireNonNull(res.getReturnStatus()) ==
BaseResult.ReturnStatus.ENTITY_ALREADY_EXISTS) {
+ throw alreadyExistsExceptionForTableLikeEntity(
+ tableIdentifier, res.getAlreadyExistsEntitySubType());
}
+ throw new IllegalStateException(
+ String.format(
+ "Unknown error status for identifier %s: %s with extraInfo: %s",
+ tableIdentifier, res.getReturnStatus(),
res.getExtraInformation()));
}
GenericTableEntity resultEntity = GenericTableEntity.of(res.getEntity());
LOGGER.debug(
@@ -146,7 +142,8 @@ public class PolarisGenericTableCatalog implements
GenericTableCatalog {
GenericTableEntity.of(
resolvedEntities == null ? null :
resolvedEntities.getRawLeafEntity());
if (null == entity) {
- throw new NoSuchTableException("Generic table does not exist: %s",
tableIdentifier);
+ throw notFoundExceptionForTableLikeEntity(
+ tableIdentifier, PolarisEntitySubType.GENERIC_TABLE);
} else {
return entity;
}
@@ -159,7 +156,8 @@ public class PolarisGenericTableCatalog implements
GenericTableCatalog {
tableIdentifier, PolarisEntityType.TABLE_LIKE,
PolarisEntitySubType.GENERIC_TABLE);
if (resolvedEntities == null) {
- throw new NoSuchTableException("Generic table does not exist: %s",
tableIdentifier);
+ throw notFoundExceptionForTableLikeEntity(
+ tableIdentifier, PolarisEntitySubType.GENERIC_TABLE);
}
List<PolarisEntity> catalogPath = resolvedEntities.getRawParentPath();
@@ -180,7 +178,7 @@ public class PolarisGenericTableCatalog implements
GenericTableCatalog {
public List<TableIdentifier> listGenericTables(Namespace namespace) {
PolarisResolvedPathWrapper resolvedEntities =
resolvedEntityView.getResolvedPath(namespace);
if (resolvedEntities == null) {
- throw new NoSuchNamespaceException("Namespace '%s' does not exist",
namespace);
+ throw noSuchNamespaceException(namespace);
}
List<PolarisEntity> catalogPath = resolvedEntities.getRawFullPath();
diff --git
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/CatalogHandlerUtils.java
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/CatalogHandlerUtils.java
index 2de9006cd..d41bf2e38 100644
---
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/CatalogHandlerUtils.java
+++
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/CatalogHandlerUtils.java
@@ -21,6 +21,8 @@ package org.apache.polaris.service.catalog.iceberg;
import static
org.apache.iceberg.TableProperties.COMMIT_MAX_RETRY_WAIT_MS_DEFAULT;
import static
org.apache.iceberg.TableProperties.COMMIT_MIN_RETRY_WAIT_MS_DEFAULT;
import static
org.apache.iceberg.TableProperties.COMMIT_TOTAL_RETRY_TIME_MS_DEFAULT;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.noSuchNamespaceException;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.notFoundExceptionForTableLikeEntity;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
@@ -59,9 +61,6 @@ import org.apache.iceberg.catalog.SupportsNamespaces;
import org.apache.iceberg.catalog.TableIdentifier;
import org.apache.iceberg.catalog.ViewCatalog;
import org.apache.iceberg.exceptions.CommitFailedException;
-import org.apache.iceberg.exceptions.NoSuchNamespaceException;
-import org.apache.iceberg.exceptions.NoSuchTableException;
-import org.apache.iceberg.exceptions.NoSuchViewException;
import org.apache.iceberg.rest.requests.CreateNamespaceRequest;
import org.apache.iceberg.rest.requests.CreateTableRequest;
import org.apache.iceberg.rest.requests.CreateViewRequest;
@@ -90,6 +89,7 @@ import org.apache.iceberg.view.ViewOperations;
import org.apache.iceberg.view.ViewRepresentation;
import org.apache.polaris.core.config.FeatureConfiguration;
import org.apache.polaris.core.config.RealmConfig;
+import org.apache.polaris.core.entity.PolarisEntitySubType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -225,7 +225,7 @@ public class CatalogHandlerUtils {
public void dropNamespace(SupportsNamespaces catalog, Namespace namespace) {
boolean dropped = catalog.dropNamespace(namespace);
if (!dropped) {
- throw new NoSuchNamespaceException("Namespace does not exist: %s",
namespace);
+ throw noSuchNamespaceException(namespace);
}
}
@@ -310,14 +310,14 @@ public class CatalogHandlerUtils {
public void dropTable(Catalog catalog, TableIdentifier ident) {
boolean dropped = catalog.dropTable(ident, false);
if (!dropped) {
- throw new NoSuchTableException("Table does not exist: %s", ident);
+ throw notFoundExceptionForTableLikeEntity(ident,
PolarisEntitySubType.ICEBERG_TABLE);
}
}
public void purgeTable(Catalog catalog, TableIdentifier ident) {
boolean dropped = catalog.dropTable(ident, true);
if (!dropped) {
- throw new NoSuchTableException("Table does not exist: %s", ident);
+ throw notFoundExceptionForTableLikeEntity(ident,
PolarisEntitySubType.ICEBERG_TABLE);
}
}
@@ -330,7 +330,7 @@ public class CatalogHandlerUtils {
.build();
} else if (table instanceof BaseMetadataTable) {
// metadata tables are loaded on the client side, return
NoSuchTableException for now
- throw new NoSuchTableException("Table does not exist: %s",
ident.toString());
+ throw notFoundExceptionForTableLikeEntity(ident,
PolarisEntitySubType.ICEBERG_TABLE);
}
throw new IllegalStateException("Cannot wrap catalog that does not produce
BaseTable");
@@ -742,7 +742,7 @@ public class CatalogHandlerUtils {
public void dropView(ViewCatalog catalog, TableIdentifier viewIdentifier) {
boolean dropped = catalog.dropView(viewIdentifier);
if (!dropped) {
- throw new NoSuchViewException("View does not exist: %s", viewIdentifier);
+ throw notFoundExceptionForTableLikeEntity(viewIdentifier,
PolarisEntitySubType.ICEBERG_VIEW);
}
}
diff --git
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java
index 3aa22eada..776a0a8b4 100644
---
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java
+++
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java
@@ -18,6 +18,11 @@
*/
package org.apache.polaris.service.catalog.iceberg;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.alreadyExistsExceptionForTableLikeEntity;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.alreadyExistsExceptionWithSameNameForTableLikeEntity;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.entityNameForSubType;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.noSuchNamespaceException;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.notFoundExceptionForTableLikeEntity;
import static
org.apache.polaris.service.exception.IcebergExceptionMapper.isStorageProviderRetryableException;
import com.google.common.annotations.VisibleForTesting;
@@ -301,7 +306,8 @@ public class IcebergCatalog extends BaseMetastoreViewCatalog
// Throw an exception if this table already exists in the catalog.
if (tableExists(identifier)) {
- throw new AlreadyExistsException("Table already exists: %s", identifier);
+ throw alreadyExistsExceptionForTableLikeEntity(
+ identifier, PolarisEntitySubType.ICEBERG_TABLE);
}
String locationDir = metadataFileLocation.substring(0, lastSlashIndex);
@@ -364,8 +370,7 @@ public class IcebergCatalog extends BaseMetastoreViewCatalog
PolarisResolvedPathWrapper resolvedNamespace =
resolvedEntityView.getResolvedPath(tableIdentifier.namespace());
if (resolvedNamespace == null) {
- throw new NoSuchNamespaceException(
- "Namespace does not exist: %s", tableIdentifier.namespace());
+ throw noSuchNamespaceException(tableIdentifier.namespace());
}
List<PolarisEntity> namespacePath = resolvedNamespace.getRawFullPath();
String namespaceLocation = resolveLocationForPath(diagnostics,
namespacePath);
@@ -689,7 +694,7 @@ public class IcebergCatalog extends BaseMetastoreViewCatalog
throws NoSuchNamespaceException {
PolarisResolvedPathWrapper resolvedEntities =
resolvedEntityView.getResolvedPath(namespace);
if (resolvedEntities == null) {
- throw new NoSuchNamespaceException("Namespace does not exist: %s",
namespace);
+ throw noSuchNamespaceException(namespace);
}
PolarisEntity entity = resolvedEntities.getRawLeafEntity();
Map<String, String> newProperties = new
HashMap<>(entity.getPropertiesAsMap());
@@ -735,7 +740,7 @@ public class IcebergCatalog extends BaseMetastoreViewCatalog
throws NoSuchNamespaceException {
PolarisResolvedPathWrapper resolvedEntities =
resolvedEntityView.getResolvedPath(namespace);
if (resolvedEntities == null) {
- throw new NoSuchNamespaceException("Namespace does not exist: %s",
namespace);
+ throw noSuchNamespaceException(namespace);
}
PolarisEntity entity = resolvedEntities.getRawLeafEntity();
@@ -767,7 +772,7 @@ public class IcebergCatalog extends BaseMetastoreViewCatalog
throws NoSuchNamespaceException {
PolarisResolvedPathWrapper resolvedEntities =
resolvedEntityView.getResolvedPath(namespace);
if (resolvedEntities == null) {
- throw new NoSuchNamespaceException("Namespace does not exist: %s",
namespace);
+ throw noSuchNamespaceException(namespace);
}
NamespaceEntity entity =
NamespaceEntity.of(resolvedEntities.getRawLeafEntity());
Preconditions.checkState(
@@ -793,7 +798,7 @@ public class IcebergCatalog extends BaseMetastoreViewCatalog
throws NoSuchNamespaceException {
PolarisResolvedPathWrapper resolvedEntities =
resolvedEntityView.getResolvedPath(namespace);
if (resolvedEntities == null) {
- throw new NoSuchNamespaceException("Namespace does not exist: %s",
namespace);
+ throw noSuchNamespaceException(namespace);
}
List<PolarisEntity> catalogPath = resolvedEntities.getRawFullPath();
@@ -850,7 +855,7 @@ public class IcebergCatalog extends BaseMetastoreViewCatalog
if (isValidIdentifier(identifier)) {
ViewOperations ops = newViewOps(identifier);
if (ops.current() == null) {
- throw new NoSuchViewException("View does not exist: %s", identifier);
+ throw notFoundExceptionForTableLikeEntity(identifier,
PolarisEntitySubType.ICEBERG_VIEW);
}
return new BaseView(ops, ViewUtil.fullViewName(name(), identifier));
}
@@ -1389,7 +1394,8 @@ public class IcebergCatalog extends
BaseMetastoreViewCatalog
} else {
// when current is non-null, the table exists. but when base is
null, the commit is trying
// to create the table
- throw new AlreadyExistsException("Table already exists: %s",
fullTableName);
+ throw alreadyExistsExceptionForTableLikeEntity(
+ fullTableName, PolarisEntitySubType.ICEBERG_TABLE);
}
}
// if the metadata is not changed, return early
@@ -1568,13 +1574,9 @@ public class IcebergCatalog extends
BaseMetastoreViewCatalog
resolvedEntityView.getPassthroughResolvedPath(
tableIdentifier, PolarisEntityType.TABLE_LIKE,
PolarisEntitySubType.ANY_SUBTYPE);
if (resolvedPath != null && resolvedPath.getRawLeafEntity() != null) {
- if (resolvedPath.getRawLeafEntity().getSubType() ==
PolarisEntitySubType.ICEBERG_VIEW) {
- throw new AlreadyExistsException(
- "View with same name already exists: %s", tableIdentifier);
- } else if (resolvedPath.getRawLeafEntity().getSubType()
- == PolarisEntitySubType.GENERIC_TABLE) {
- throw new AlreadyExistsException(
- "Generic table with same name already exists: %s",
tableIdentifier);
+ var subType = resolvedPath.getRawLeafEntity().getSubType();
+ if (subType != PolarisEntitySubType.ICEBERG_TABLE) {
+ throw
alreadyExistsExceptionWithSameNameForTableLikeEntity(tableIdentifier, subType);
}
}
Map<String, String> storedProperties =
buildTableMetadataPropertiesMap(metadata);
@@ -1606,11 +1608,13 @@ public class IcebergCatalog extends
BaseMetastoreViewCatalog
}
if (!Objects.equal(existingLocation, oldLocation)) {
if (null == base) {
- throw new AlreadyExistsException("Table already exists: %s",
fullTableName);
+ throw alreadyExistsExceptionForTableLikeEntity(
+ fullTableName, PolarisEntitySubType.ICEBERG_TABLE);
}
if (null == existingLocation) {
- throw new NoSuchTableException("Table does not exist: %s",
fullTableName);
+ throw notFoundExceptionForTableLikeEntity(
+ fullTableName, PolarisEntitySubType.ICEBERG_TABLE);
}
throw new CommitFailedException(
@@ -1828,7 +1832,8 @@ public class IcebergCatalog extends
BaseMetastoreViewCatalog
} else {
// when current is non-null, the view exists. but when base is null,
the commit is trying
// to create the view
- throw new AlreadyExistsException("View already exists: %s",
viewName());
+ throw alreadyExistsExceptionForTableLikeEntity(
+ identifier, PolarisEntitySubType.ICEBERG_VIEW);
}
}
@@ -1925,7 +1930,8 @@ public class IcebergCatalog extends
BaseMetastoreViewCatalog
resolvedEntityView.getPassthroughResolvedPath(
identifier, PolarisEntityType.TABLE_LIKE,
PolarisEntitySubType.ICEBERG_TABLE);
if (resolvedTable != null) {
- throw new AlreadyExistsException("Table with same name already exists:
%s", identifier);
+ throw alreadyExistsExceptionWithSameNameForTableLikeEntity(
+ identifier, PolarisEntitySubType.ICEBERG_TABLE);
}
PolarisResolvedPathWrapper resolvedEntities =
@@ -1989,11 +1995,12 @@ public class IcebergCatalog extends
BaseMetastoreViewCatalog
}
if (!Objects.equal(existingLocation, oldLocation)) {
if (null == base) {
- throw new AlreadyExistsException("View already exists: %s",
identifier);
+ throw alreadyExistsExceptionForTableLikeEntity(
+ identifier, PolarisEntitySubType.ICEBERG_VIEW);
}
if (null == existingLocation) {
- throw new NoSuchViewException("View does not exist: %s", identifier);
+ throw notFoundExceptionForTableLikeEntity(identifier,
PolarisEntitySubType.ICEBERG_VIEW);
}
throw new CommitFailedException(
@@ -2258,19 +2265,9 @@ public class IcebergCatalog extends
BaseMetastoreViewCatalog
{
PolarisEntitySubType existingEntitySubType =
returnedEntityResult.getAlreadyExistsEntitySubType();
- if (existingEntitySubType == null) {
- // this code path is unexpected
- throw new AlreadyExistsException(
- "Cannot rename %s to %s. Object already exists", from, to);
- } else if (existingEntitySubType ==
PolarisEntitySubType.ICEBERG_TABLE) {
- throw new AlreadyExistsException(
- "Cannot rename %s to %s. Table already exists", from, to);
- } else if (existingEntitySubType ==
PolarisEntitySubType.ICEBERG_VIEW) {
- throw new AlreadyExistsException(
- "Cannot rename %s to %s. View already exists", from, to);
- }
- throw new IllegalStateException(
- String.format("Unexpected entity type '%s'",
existingEntitySubType));
+ throw new AlreadyExistsException(
+ "Cannot rename %s to %s. %s already exists",
+ from, to, entityNameForSubType(existingEntitySubType));
}
case BaseResult.ReturnStatus.ENTITY_NOT_FOUND:
@@ -2373,8 +2370,8 @@ public class IcebergCatalog extends
BaseMetastoreViewCatalog
throw new NotFoundException("Parent path does not exist for %s",
identifier);
case BaseResult.ReturnStatus.ENTITY_ALREADY_EXISTS:
- throw new AlreadyExistsException(
- "Iceberg table, view, or generic table already exists: %s",
identifier);
+ throw alreadyExistsExceptionForTableLikeEntity(
+ identifier, res.getAlreadyExistsEntitySubType());
default:
throw new IllegalStateException(
String.format(
diff --git
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java
index 599ff152e..0c5b0502c 100644
---
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java
+++
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java
@@ -21,6 +21,8 @@ package org.apache.polaris.service.catalog.iceberg;
import static
org.apache.polaris.core.config.FeatureConfiguration.ALLOW_FEDERATED_CATALOGS_CREDENTIAL_VENDING;
import static
org.apache.polaris.core.config.FeatureConfiguration.LIST_PAGINATION_ENABLED;
import static
org.apache.polaris.service.catalog.AccessDelegationMode.VENDED_CREDENTIALS;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.alreadyExistsExceptionForTableLikeEntity;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.notFoundExceptionForTableLikeEntity;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -63,7 +65,6 @@ import org.apache.iceberg.exceptions.AlreadyExistsException;
import org.apache.iceberg.exceptions.BadRequestException;
import org.apache.iceberg.exceptions.CommitFailedException;
import org.apache.iceberg.exceptions.ForbiddenException;
-import org.apache.iceberg.exceptions.NoSuchTableException;
import org.apache.iceberg.exceptions.NotFoundException;
import org.apache.iceberg.metrics.ScanReport;
import org.apache.iceberg.rest.Endpoint;
@@ -478,7 +479,8 @@ public abstract class IcebergCatalogHandler extends
CatalogHandler implements Au
TableIdentifier tableIdentifier = TableIdentifier.of(namespace,
request.name());
if (baseCatalog.tableExists(tableIdentifier)) {
- throw new AlreadyExistsException("Table already exists: %s",
tableIdentifier);
+ throw alreadyExistsExceptionForTableLikeEntity(
+ tableIdentifier, PolarisEntitySubType.ICEBERG_TABLE);
}
Map<String, String> properties = Maps.newHashMap();
@@ -508,7 +510,8 @@ public abstract class IcebergCatalogHandler extends
CatalogHandler implements Au
.build();
} else if (table instanceof BaseMetadataTable) {
// metadata tables are loaded on the client side, return
NoSuchTableException for now
- throw new NoSuchTableException("Table does not exist: %s",
tableIdentifier.toString());
+ throw notFoundExceptionForTableLikeEntity(
+ tableIdentifier, PolarisEntitySubType.ICEBERG_TABLE);
}
throw new IllegalStateException("Cannot wrap catalog that does not produce
BaseTable");
@@ -519,7 +522,7 @@ public abstract class IcebergCatalogHandler extends
CatalogHandler implements Au
TableIdentifier ident = TableIdentifier.of(namespace, request.name());
if (baseCatalog.tableExists(ident)) {
- throw new AlreadyExistsException("Table already exists: %s", ident);
+ throw alreadyExistsExceptionForTableLikeEntity(ident,
PolarisEntitySubType.ICEBERG_TABLE);
}
Map<String, String> properties = Maps.newHashMap();
@@ -828,7 +831,8 @@ public abstract class IcebergCatalogHandler extends
CatalogHandler implements Au
return Optional.of(filterResponseToSnapshots(response, snapshots));
} else if (table instanceof BaseMetadataTable) {
// metadata tables are loaded on the client side, return
NoSuchTableException for now
- throw new NoSuchTableException("Table does not exist: %s",
tableIdentifier.toString());
+ throw notFoundExceptionForTableLikeEntity(
+ tableIdentifier, PolarisEntitySubType.ICEBERG_TABLE);
}
throw new IllegalStateException("Cannot wrap catalog that does not produce
BaseTable");
diff --git
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalog.java
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalog.java
index 5c2a70da2..147f55051 100644
---
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalog.java
+++
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalog.java
@@ -20,6 +20,8 @@ package org.apache.polaris.service.catalog.policy;
import static
org.apache.polaris.core.persistence.dao.entity.BaseResult.ReturnStatus.POLICY_HAS_MAPPINGS;
import static
org.apache.polaris.core.persistence.dao.entity.BaseResult.ReturnStatus.POLICY_MAPPING_OF_SAME_TYPE_ALREADY_EXISTS;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.noSuchNamespaceException;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.notFoundExceptionForTableLikeEntity;
import static
org.apache.polaris.service.types.PolicyAttachmentTarget.TypeEnum.CATALOG;
import com.google.common.base.Strings;
@@ -38,8 +40,6 @@ import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.catalog.TableIdentifier;
import org.apache.iceberg.exceptions.AlreadyExistsException;
import org.apache.iceberg.exceptions.BadRequestException;
-import org.apache.iceberg.exceptions.NoSuchNamespaceException;
-import org.apache.iceberg.exceptions.NoSuchTableException;
import org.apache.polaris.core.context.CallContext;
import org.apache.polaris.core.entity.CatalogEntity;
import org.apache.polaris.core.entity.PolarisEntity;
@@ -448,7 +448,7 @@ public class PolicyCatalog {
// namespace
var resolvedTargetEntity = resolvedEntityView.getResolvedPath(namespace);
if (resolvedTargetEntity == null) {
- throw new NoSuchNamespaceException("Namespace does not exist: %s",
namespace);
+ throw noSuchNamespaceException(namespace);
}
return resolvedTargetEntity.getRawFullPath();
} else {
@@ -459,7 +459,8 @@ public class PolicyCatalog {
resolvedEntityView.getResolvedPath(
tableIdentifier, PolarisEntityType.TABLE_LIKE,
PolarisEntitySubType.ICEBERG_TABLE);
if (resolvedTableEntity == null) {
- throw new NoSuchTableException("Iceberg Table does not exist: %s",
tableIdentifier);
+ throw notFoundExceptionForTableLikeEntity(
+ tableIdentifier, PolarisEntitySubType.ICEBERG_TABLE);
}
return resolvedTableEntity.getRawFullPath();
}
diff --git
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogHandler.java
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogHandler.java
index 20a6d5adc..1fe29ae41 100644
---
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogHandler.java
+++
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogHandler.java
@@ -18,6 +18,8 @@
*/
package org.apache.polaris.service.catalog.policy;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.noSuchNamespaceException;
+
import com.google.common.base.Strings;
import jakarta.annotation.Nullable;
import java.util.Arrays;
@@ -25,7 +27,6 @@ import java.util.HashSet;
import java.util.List;
import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.catalog.TableIdentifier;
-import org.apache.iceberg.exceptions.NoSuchNamespaceException;
import org.apache.iceberg.exceptions.NoSuchTableException;
import org.apache.iceberg.exceptions.NotFoundException;
import org.apache.polaris.core.auth.PolarisAuthorizableOperation;
@@ -296,8 +297,7 @@ public abstract class PolicyCatalogHandler extends
CatalogHandler {
PolarisCatalogHelpers.listToTableIdentifier(
status.getFailedToResolvePath().entityNames()));
case PolarisEntityType.NAMESPACE ->
- throw new NoSuchNamespaceException(
- "Namespace does not exist: %s",
+ throw noSuchNamespaceException(
Namespace.of(status.getFailedToResolvePath().entityNames().toArray(new
String[0])));
case PolarisEntityType.POLICY ->
throw new NoSuchPolicyException(String.format("Policy does not
exist: %s", identifier));
diff --git
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogUtils.java
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogUtils.java
index 173ddf50e..ede8f864b 100644
---
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogUtils.java
+++
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogUtils.java
@@ -18,11 +18,12 @@
*/
package org.apache.polaris.service.catalog.policy;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.noSuchNamespaceException;
+import static
org.apache.polaris.service.catalog.common.ExceptionUtils.notFoundExceptionForTableLikeEntity;
+
import jakarta.annotation.Nonnull;
import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.catalog.TableIdentifier;
-import org.apache.iceberg.exceptions.NoSuchNamespaceException;
-import org.apache.iceberg.exceptions.NoSuchTableException;
import org.apache.polaris.core.entity.PolarisEntitySubType;
import org.apache.polaris.core.entity.PolarisEntityType;
import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper;
@@ -41,7 +42,7 @@ public class PolicyCatalogUtils {
var namespace = Namespace.of(target.getPath().toArray(new String[0]));
var resolvedTargetEntity =
resolutionManifest.getResolvedPath(namespace);
if (resolvedTargetEntity == null) {
- throw new NoSuchNamespaceException("Namespace does not exist: %s",
namespace);
+ throw noSuchNamespaceException(namespace);
}
yield resolvedTargetEntity;
}
@@ -52,7 +53,8 @@ public class PolicyCatalogUtils {
resolutionManifest.getResolvedPath(
tableIdentifier, PolarisEntityType.TABLE_LIKE,
PolarisEntitySubType.ICEBERG_TABLE);
if (resolvedTableEntity == null) {
- throw new NoSuchTableException("Iceberg Table does not exist: %s",
tableIdentifier);
+ throw notFoundExceptionForTableLikeEntity(
+ tableIdentifier, PolarisEntitySubType.ICEBERG_TABLE);
}
yield resolvedTableEntity;
}