diff --git a/polaris-core/src/main/java/org/apache/polaris/core/exceptions/AlreadyExistsException.java b/polaris-core/src/main/java/org/apache/polaris/core/exceptions/AlreadyExistsException.java index a941a549cf0..72511b10da6 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/exceptions/AlreadyExistsException.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/exceptions/AlreadyExistsException.java @@ -18,6 +18,8 @@ */ package org.apache.polaris.core.exceptions; +import jakarta.ws.rs.core.Response; + /** * A {@link PolarisException} implementation for when Polaris is unable to create an entity that * already exists. @@ -30,4 +32,9 @@ public AlreadyExistsException(String message) { public AlreadyExistsException(String message, Throwable cause) { super(message, cause); } + + @Override + public int httpStatusCode() { + return Response.Status.CONFLICT.getStatusCode(); + } } diff --git a/polaris-core/src/main/java/org/apache/polaris/core/exceptions/CommitConflictException.java b/polaris-core/src/main/java/org/apache/polaris/core/exceptions/CommitConflictException.java index a1e11cd0038..d643f7a9e9a 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/exceptions/CommitConflictException.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/exceptions/CommitConflictException.java @@ -20,6 +20,7 @@ package org.apache.polaris.core.exceptions; import com.google.errorprone.annotations.FormatMethod; +import jakarta.ws.rs.core.Response; public class CommitConflictException extends PolarisException { public CommitConflictException(String message) { @@ -39,4 +40,9 @@ public CommitConflictException(Throwable cause, String message, Object... args) public CommitConflictException(String message, Throwable cause) { super(message, cause); } + + @Override + public int httpStatusCode() { + return Response.Status.CONFLICT.getStatusCode(); + } } diff --git a/polaris-core/src/main/java/org/apache/polaris/core/exceptions/FileIOUnknownHostException.java b/polaris-core/src/main/java/org/apache/polaris/core/exceptions/FileIOUnknownHostException.java index 2e830205afa..9fa26bb74b0 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/exceptions/FileIOUnknownHostException.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/exceptions/FileIOUnknownHostException.java @@ -18,6 +18,8 @@ */ package org.apache.polaris.core.exceptions; +import jakarta.ws.rs.core.Response; + /** * A {@link PolarisException} implementation for when an UnknownHostException happens during File IO * to S3, GCS, or Azure. @@ -26,4 +28,9 @@ public class FileIOUnknownHostException extends PolarisException { public FileIOUnknownHostException(String message, Throwable cause) { super(message, cause); } + + @Override + public int httpStatusCode() { + return Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(); + } } diff --git a/polaris-core/src/main/java/org/apache/polaris/core/exceptions/PolarisException.java b/polaris-core/src/main/java/org/apache/polaris/core/exceptions/PolarisException.java index 96ef9cf7c38..80151f4a593 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/exceptions/PolarisException.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/exceptions/PolarisException.java @@ -22,6 +22,7 @@ * Base class for Polaris-specific runtime exceptions. * *
All custom exceptions in Polaris should extend this class to provide specific error details.
+ * Subclasses must implement {@link #httpStatusCode()} to declare their HTTP response status.
*/
public abstract class PolarisException extends RuntimeException {
@@ -32,4 +33,10 @@ public PolarisException(String message) {
public PolarisException(String message, Throwable cause) {
super(message, cause);
}
+
+ /**
+ * Returns the HTTP status code that should be used when this exception is mapped to an HTTP
+ * response.
+ */
+ public abstract int httpStatusCode();
}
diff --git a/polaris-core/src/main/java/org/apache/polaris/core/exceptions/PolarisServiceUnavailableException.java b/polaris-core/src/main/java/org/apache/polaris/core/exceptions/PolarisServiceUnavailableException.java
index 5479fd9f94b..fa596bf2875 100644
--- a/polaris-core/src/main/java/org/apache/polaris/core/exceptions/PolarisServiceUnavailableException.java
+++ b/polaris-core/src/main/java/org/apache/polaris/core/exceptions/PolarisServiceUnavailableException.java
@@ -19,6 +19,7 @@
package org.apache.polaris.core.exceptions;
import com.google.errorprone.annotations.FormatMethod;
+import jakarta.ws.rs.core.Response;
/**
* Signals a transient failure that the client may resolve by retrying. Mapped to HTTP 503 (Service
@@ -37,4 +38,9 @@ public PolarisServiceUnavailableException(int retryAfterSeconds, String message,
public int getRetryAfterSeconds() {
return retryAfterSeconds;
}
+
+ @Override
+ public int httpStatusCode() {
+ return Response.Status.SERVICE_UNAVAILABLE.getStatusCode();
+ }
}
diff --git a/polaris-core/src/main/java/org/apache/polaris/core/persistence/PolicyMappingAlreadyExistsException.java b/polaris-core/src/main/java/org/apache/polaris/core/persistence/PolicyMappingAlreadyExistsException.java
index a31e500b0b3..9223fa91909 100644
--- a/polaris-core/src/main/java/org/apache/polaris/core/persistence/PolicyMappingAlreadyExistsException.java
+++ b/polaris-core/src/main/java/org/apache/polaris/core/persistence/PolicyMappingAlreadyExistsException.java
@@ -19,6 +19,7 @@
package org.apache.polaris.core.persistence;
import com.google.errorprone.annotations.FormatMethod;
+import jakarta.ws.rs.core.Response;
import org.apache.polaris.core.exceptions.PolarisException;
import org.apache.polaris.core.policy.PolarisPolicyMappingRecord;
@@ -45,4 +46,9 @@ public PolicyMappingAlreadyExistsException(String message, Object... arg) {
public PolarisPolicyMappingRecord getExistingRecord() {
return this.existingRecord;
}
+
+ @Override
+ public int httpStatusCode() {
+ return Response.Status.CONFLICT.getStatusCode();
+ }
}
diff --git a/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/NoSuchPolicyException.java b/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/NoSuchPolicyException.java
index 642bd36adb3..a9157d04dc0 100644
--- a/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/NoSuchPolicyException.java
+++ b/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/NoSuchPolicyException.java
@@ -18,6 +18,7 @@
*/
package org.apache.polaris.core.policy.exceptions;
+import jakarta.ws.rs.core.Response;
import org.apache.polaris.core.exceptions.PolarisException;
public class NoSuchPolicyException extends PolarisException {
@@ -29,4 +30,9 @@ public NoSuchPolicyException(String message) {
public NoSuchPolicyException(String message, Throwable cause) {
super(message, cause);
}
+
+ @Override
+ public int httpStatusCode() {
+ return Response.Status.NOT_FOUND.getStatusCode();
+ }
}
diff --git a/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/PolicyAttachException.java b/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/PolicyAttachException.java
index e47d978d0fd..cc24b6f70ad 100644
--- a/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/PolicyAttachException.java
+++ b/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/PolicyAttachException.java
@@ -19,6 +19,7 @@
package org.apache.polaris.core.policy.exceptions;
import com.google.errorprone.annotations.FormatMethod;
+import jakarta.ws.rs.core.Response;
import org.apache.polaris.core.exceptions.PolarisException;
public class PolicyAttachException extends PolarisException {
@@ -31,4 +32,9 @@ public PolicyAttachException(String message, Object... args) {
public PolicyAttachException(Throwable cause, String message, Object... args) {
super(String.format(message, args), cause);
}
+
+ @Override
+ public int httpStatusCode() {
+ return Response.Status.BAD_REQUEST.getStatusCode();
+ }
}
diff --git a/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/PolicyInUseException.java b/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/PolicyInUseException.java
index 14d165497e1..616a01e7e80 100644
--- a/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/PolicyInUseException.java
+++ b/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/PolicyInUseException.java
@@ -19,6 +19,7 @@
package org.apache.polaris.core.policy.exceptions;
import com.google.errorprone.annotations.FormatMethod;
+import jakarta.ws.rs.core.Response;
import org.apache.polaris.core.exceptions.PolarisException;
public class PolicyInUseException extends PolarisException {
@@ -31,4 +32,9 @@ public PolicyInUseException(String message, Object... args) {
public PolicyInUseException(Throwable cause, String message, Object... args) {
super(String.format(message, args), cause);
}
+
+ @Override
+ public int httpStatusCode() {
+ return Response.Status.BAD_REQUEST.getStatusCode();
+ }
}
diff --git a/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/PolicyVersionMismatchException.java b/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/PolicyVersionMismatchException.java
index c2f8f8f78e1..95b10040205 100644
--- a/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/PolicyVersionMismatchException.java
+++ b/polaris-core/src/main/java/org/apache/polaris/core/policy/exceptions/PolicyVersionMismatchException.java
@@ -18,6 +18,7 @@
*/
package org.apache.polaris.core.policy.exceptions;
+import jakarta.ws.rs.core.Response;
import org.apache.polaris.core.exceptions.PolarisException;
public class PolicyVersionMismatchException extends PolarisException {
@@ -28,4 +29,9 @@ public PolicyVersionMismatchException(String message) {
public PolicyVersionMismatchException(String message, Throwable cause) {
super(message, cause);
}
+
+ @Override
+ public int httpStatusCode() {
+ return Response.Status.CONFLICT.getStatusCode();
+ }
}
diff --git a/polaris-core/src/main/java/org/apache/polaris/core/policy/validator/InvalidPolicyException.java b/polaris-core/src/main/java/org/apache/polaris/core/policy/validator/InvalidPolicyException.java
index 9672cfa617b..e91d0c735ee 100644
--- a/polaris-core/src/main/java/org/apache/polaris/core/policy/validator/InvalidPolicyException.java
+++ b/polaris-core/src/main/java/org/apache/polaris/core/policy/validator/InvalidPolicyException.java
@@ -18,6 +18,7 @@
*/
package org.apache.polaris.core.policy.validator;
+import jakarta.ws.rs.core.Response;
import org.apache.polaris.core.exceptions.PolarisException;
/** Exception thrown when a policy is invalid or violates defined rules. */
@@ -33,4 +34,9 @@ public InvalidPolicyException(String message, Throwable cause) {
public InvalidPolicyException(Throwable cause) {
super("Invalid policy", cause);
}
+
+ @Override
+ public int httpStatusCode() {
+ return Response.Status.BAD_REQUEST.getStatusCode();
+ }
}
diff --git a/runtime/service/src/main/java/org/apache/polaris/service/exception/PolarisExceptionMapper.java b/runtime/service/src/main/java/org/apache/polaris/service/exception/PolarisExceptionMapper.java
index 97d77de7dbd..b3ed74bf299 100644
--- a/runtime/service/src/main/java/org/apache/polaris/service/exception/PolarisExceptionMapper.java
+++ b/runtime/service/src/main/java/org/apache/polaris/service/exception/PolarisExceptionMapper.java
@@ -25,64 +25,37 @@
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import org.apache.iceberg.rest.responses.ErrorResponse;
-import org.apache.polaris.core.exceptions.AlreadyExistsException;
-import org.apache.polaris.core.exceptions.CommitConflictException;
import org.apache.polaris.core.exceptions.PolarisException;
import org.apache.polaris.core.exceptions.PolarisServiceUnavailableException;
-import org.apache.polaris.core.persistence.PolicyMappingAlreadyExistsException;
-import org.apache.polaris.core.policy.exceptions.NoSuchPolicyException;
-import org.apache.polaris.core.policy.exceptions.PolicyAttachException;
-import org.apache.polaris.core.policy.exceptions.PolicyInUseException;
-import org.apache.polaris.core.policy.exceptions.PolicyVersionMismatchException;
-import org.apache.polaris.core.policy.validator.InvalidPolicyException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;
/**
- * An {@link ExceptionMapper} implementation for {@link PolarisException}s modeled after {@link
- * IcebergExceptionMapper}
+ * An {@link ExceptionMapper} implementation for {@link PolarisException}s. Delegates HTTP status
+ * resolution to {@link PolarisException#httpStatusCode()}.
*/
@Provider
public class PolarisExceptionMapper implements ExceptionMapper