From 76cddcbb820110762731237679d809c6f73283b5 Mon Sep 17 00:00:00 2001 From: anitarua Date: Fri, 1 Nov 2024 13:36:13 -0700 Subject: [PATCH 1/3] chore: improve resource exhausted error message --- .../CacheServiceExceptionMapper.java | 3 +- .../exceptions/LimitExceededException.java | 87 +++++++++++++++++-- 2 files changed, 82 insertions(+), 8 deletions(-) diff --git a/momento-sdk/src/main/java/momento/sdk/exceptions/CacheServiceExceptionMapper.java b/momento-sdk/src/main/java/momento/sdk/exceptions/CacheServiceExceptionMapper.java index 4df14d59..7a043e65 100644 --- a/momento-sdk/src/main/java/momento/sdk/exceptions/CacheServiceExceptionMapper.java +++ b/momento-sdk/src/main/java/momento/sdk/exceptions/CacheServiceExceptionMapper.java @@ -66,7 +66,8 @@ public static SdkException convert(Throwable e) { return new AuthenticationException(grpcException, errorDetails); case RESOURCE_EXHAUSTED: - return new LimitExceededException(grpcException, errorDetails); + return LimitExceededException.CreateWithMessageWrapper( + grpcException, errorDetails, errorCause); case NOT_FOUND: if (errorCause.contains("item_not_found")) { diff --git a/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededException.java b/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededException.java index 1eb9ddaa..cbc26576 100644 --- a/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededException.java +++ b/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededException.java @@ -4,19 +4,92 @@ /** Requested operation couldn't be completed because system limits were hit. */ public class LimitExceededException extends MomentoServiceException { - - private static final String MESSAGE = - "Request rate, bandwidth, or object size exceeded the limits for this account. To resolve this error, " - + "reduce your usage as appropriate or contact Momento to request a limit increase."; - /** * Constructs a LimitExceededException with a cause and error details. * * @param cause the cause. * @param transportErrorDetails details about the request and error. + * @param messageWrapper details about which limit was exceeded. */ public LimitExceededException( - Throwable cause, MomentoTransportErrorDetails transportErrorDetails) { - super(MomentoErrorCode.LIMIT_EXCEEDED_ERROR, MESSAGE, cause, transportErrorDetails); + Throwable cause, MomentoTransportErrorDetails transportErrorDetails, String messageWrapper) { + super(MomentoErrorCode.LIMIT_EXCEEDED_ERROR, messageWrapper, cause, transportErrorDetails); + } + + /** + * Creates a LimitExceededException with a cause and error details. Determines the limit exceeded + * message wrapper to use based on the error cause. + * + * @param cause + * @param transportErrorDetails + * @param errorCause + * @return + */ + public static LimitExceededException CreateWithMessageWrapper( + Throwable cause, MomentoTransportErrorDetails transportErrorDetails, String errorCause) { + String messageWrapper = LimitExceededMessageWrapper.UNKNOWN_LIMIT_EXCEEDED.toString(); + switch (errorCause) { + case "topic_subscriptions_limit_exceeded": + messageWrapper = LimitExceededMessageWrapper.TOPIC_SUBSCRIPTIONS_LIMIT_EXCEEDED.toString(); + break; + case "operations_rate_limit_exceeded": + messageWrapper = LimitExceededMessageWrapper.OPERATIONS_RATE_LIMIT_EXCEEDED.toString(); + break; + case "throughput_rate_limit_exceeded": + messageWrapper = LimitExceededMessageWrapper.THROUGHPUT_RATE_LIMIT_EXCEEDED.toString(); + break; + case "request_size_limit_exceeded": + messageWrapper = LimitExceededMessageWrapper.REQUEST_SIZE_LIMIT_EXCEEDED.toString(); + break; + case "item_size_limit_exceeded": + messageWrapper = LimitExceededMessageWrapper.ITEM_SIZE_LIMIT_EXCEEDED.toString(); + break; + case "element_size_limit_exceeded": + messageWrapper = LimitExceededMessageWrapper.ELEMENT_SIZE_LIMIT_EXCEEDED.toString(); + break; + default: + String lowerCasedMessage = errorCause.toLowerCase(); + if (lowerCasedMessage.contains("subscribers")) { + messageWrapper = + LimitExceededMessageWrapper.TOPIC_SUBSCRIPTIONS_LIMIT_EXCEEDED.toString(); + } else if (lowerCasedMessage.contains("operations")) { + messageWrapper = LimitExceededMessageWrapper.OPERATIONS_RATE_LIMIT_EXCEEDED.toString(); + } else if (lowerCasedMessage.contains("throughput")) { + messageWrapper = LimitExceededMessageWrapper.THROUGHPUT_RATE_LIMIT_EXCEEDED.toString(); + } else if (lowerCasedMessage.contains("request limit")) { + messageWrapper = LimitExceededMessageWrapper.REQUEST_SIZE_LIMIT_EXCEEDED.toString(); + } else if (lowerCasedMessage.contains("item size")) { + messageWrapper = LimitExceededMessageWrapper.ITEM_SIZE_LIMIT_EXCEEDED.toString(); + } else if (lowerCasedMessage.contains("element size")) { + messageWrapper = LimitExceededMessageWrapper.ELEMENT_SIZE_LIMIT_EXCEEDED.toString(); + } + break; + } + return new LimitExceededException(cause, transportErrorDetails, messageWrapper); + } +} + +enum LimitExceededMessageWrapper { + TOPIC_SUBSCRIPTIONS_LIMIT_EXCEEDED("Topic subscriptions limit exceeded for this account"), + OPERATIONS_RATE_LIMIT_EXCEEDED("Request rate limit exceeded for this account"), + THROUGHPUT_RATE_LIMIT_EXCEEDED("Bandwidth limit exceeded for this account"), + REQUEST_SIZE_LIMIT_EXCEEDED("Request size limit exceeded for this account"), + ITEM_SIZE_LIMIT_EXCEEDED("Item size limit exceeded for this account"), + ELEMENT_SIZE_LIMIT_EXCEEDED("Element size limit exceeded for this account"), + UNKNOWN_LIMIT_EXCEEDED("Limit exceeded for this account"); + + private final String messageWrapper; + + /** @param messageWrapper */ + LimitExceededMessageWrapper(final String messageWrapper) { + this.messageWrapper = messageWrapper; + } + + /* (non-Javadoc) + * @see java.lang.Enum#toString() + */ + @Override + public String toString() { + return messageWrapper; } } From 5f61fa14912b8c9d0efed1556518c928041925ca Mon Sep 17 00:00:00 2001 From: anitarua Date: Fri, 1 Nov 2024 16:43:36 -0700 Subject: [PATCH 2/3] add comments --- .../java/momento/sdk/exceptions/LimitExceededException.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededException.java b/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededException.java index cbc26576..88b3a77c 100644 --- a/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededException.java +++ b/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededException.java @@ -28,6 +28,9 @@ public LimitExceededException( public static LimitExceededException CreateWithMessageWrapper( Throwable cause, MomentoTransportErrorDetails transportErrorDetails, String errorCause) { String messageWrapper = LimitExceededMessageWrapper.UNKNOWN_LIMIT_EXCEEDED.toString(); + + // If provided, we use the `err` metadata value to determine the most + // appropriate error message to return. switch (errorCause) { case "topic_subscriptions_limit_exceeded": messageWrapper = LimitExceededMessageWrapper.TOPIC_SUBSCRIPTIONS_LIMIT_EXCEEDED.toString(); @@ -48,6 +51,8 @@ public static LimitExceededException CreateWithMessageWrapper( messageWrapper = LimitExceededMessageWrapper.ELEMENT_SIZE_LIMIT_EXCEEDED.toString(); break; default: + // If `err` metadata is unavailable, try to use the error details field + // to return the an appropriate error message. String lowerCasedMessage = errorCause.toLowerCase(); if (lowerCasedMessage.contains("subscribers")) { messageWrapper = From 64442e36154f5e52f909c13fdf8cc7cb9b49c4a5 Mon Sep 17 00:00:00 2001 From: anitarua Date: Fri, 8 Nov 2024 09:31:35 -0800 Subject: [PATCH 3/3] move new enum to separate file --- .../exceptions/LimitExceededException.java | 25 ---------------- .../LimitExceededMessageWrapper.java | 30 +++++++++++++++++++ 2 files changed, 30 insertions(+), 25 deletions(-) create mode 100644 momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededMessageWrapper.java diff --git a/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededException.java b/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededException.java index 88b3a77c..b586ebcf 100644 --- a/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededException.java +++ b/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededException.java @@ -73,28 +73,3 @@ public static LimitExceededException CreateWithMessageWrapper( return new LimitExceededException(cause, transportErrorDetails, messageWrapper); } } - -enum LimitExceededMessageWrapper { - TOPIC_SUBSCRIPTIONS_LIMIT_EXCEEDED("Topic subscriptions limit exceeded for this account"), - OPERATIONS_RATE_LIMIT_EXCEEDED("Request rate limit exceeded for this account"), - THROUGHPUT_RATE_LIMIT_EXCEEDED("Bandwidth limit exceeded for this account"), - REQUEST_SIZE_LIMIT_EXCEEDED("Request size limit exceeded for this account"), - ITEM_SIZE_LIMIT_EXCEEDED("Item size limit exceeded for this account"), - ELEMENT_SIZE_LIMIT_EXCEEDED("Element size limit exceeded for this account"), - UNKNOWN_LIMIT_EXCEEDED("Limit exceeded for this account"); - - private final String messageWrapper; - - /** @param messageWrapper */ - LimitExceededMessageWrapper(final String messageWrapper) { - this.messageWrapper = messageWrapper; - } - - /* (non-Javadoc) - * @see java.lang.Enum#toString() - */ - @Override - public String toString() { - return messageWrapper; - } -} diff --git a/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededMessageWrapper.java b/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededMessageWrapper.java new file mode 100644 index 00000000..16042ce4 --- /dev/null +++ b/momento-sdk/src/main/java/momento/sdk/exceptions/LimitExceededMessageWrapper.java @@ -0,0 +1,30 @@ +package momento.sdk.exceptions; + +/** + * A list of all available message wrappers for the LimitExceededException. These messages specify + * which limit was exceeded for the account. + */ +public enum LimitExceededMessageWrapper { + TOPIC_SUBSCRIPTIONS_LIMIT_EXCEEDED("Topic subscriptions limit exceeded for this account"), + OPERATIONS_RATE_LIMIT_EXCEEDED("Request rate limit exceeded for this account"), + THROUGHPUT_RATE_LIMIT_EXCEEDED("Bandwidth limit exceeded for this account"), + REQUEST_SIZE_LIMIT_EXCEEDED("Request size limit exceeded for this account"), + ITEM_SIZE_LIMIT_EXCEEDED("Item size limit exceeded for this account"), + ELEMENT_SIZE_LIMIT_EXCEEDED("Element size limit exceeded for this account"), + UNKNOWN_LIMIT_EXCEEDED("Limit exceeded for this account"); + + private final String messageWrapper; + + /** @param messageWrapper */ + LimitExceededMessageWrapper(final String messageWrapper) { + this.messageWrapper = messageWrapper; + } + + /* (non-Javadoc) + * @see java.lang.Enum#toString() + */ + @Override + public String toString() { + return messageWrapper; + } +}