Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: improve resource exhausted error message #399

Merged
merged 3 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,97 @@

/** 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();

// 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();
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:
// 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 =
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;
}
anitarua marked this conversation as resolved.
Show resolved Hide resolved
}
Loading