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 #584

Merged
merged 4 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 1 addition & 2 deletions src/Momento.Sdk/Exceptions/CacheExceptionMapper.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Threading.Tasks;
using Grpc.Core;
using Microsoft.Extensions.Logging;

Expand Down Expand Up @@ -79,7 +78,7 @@ public SdkException Convert(Exception e, Metadata? transportMetadata = null)
return new AuthenticationException(ex.Message, transportDetails);

case StatusCode.ResourceExhausted:
return new LimitExceededException(ex.Message, transportDetails);
return LimitExceededException.CreateWithMessageWrapper(ex.Message, transportDetails, ex);

case StatusCode.NotFound:
return new NotFoundException(ex.Message, transportDetails);
Expand Down
85 changes: 82 additions & 3 deletions src/Momento.Sdk/Exceptions/LimitExceededException.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,94 @@
namespace Momento.Sdk.Exceptions;

using System;
using Grpc.Core;

/// <summary>
/// Requested operation couldn't be completed because system limits were hit.
/// </summary>
public class LimitExceededException : SdkException
{
/// <include file="../docs.xml" path='docs/class[@name="SdkException"]/constructor/*' />
public LimitExceededException(string message, MomentoErrorTransportDetails transportDetails, Exception? e = null) : base(MomentoErrorCode.LIMIT_EXCEEDED_ERROR, message, transportDetails, e)
public LimitExceededException(string messageWrapper, string message, MomentoErrorTransportDetails transportDetails, RpcException? e = null) : base(MomentoErrorCode.LIMIT_EXCEEDED_ERROR, message, transportDetails, e) {
this.MessageWrapper = messageWrapper;
}

/// <summary>
/// Creates a LimitExceededException with a message wrapper that specifies the limit that was exceeded.
/// </summary>
/// <param name="message"></param>
/// <param name="transportDetails"></param>
/// <param name="e"></param>
/// <returns></returns>
public static LimitExceededException CreateWithMessageWrapper(string message, MomentoErrorTransportDetails transportDetails, RpcException? e = null)
{
this.MessageWrapper = "Request rate exceeded the limits for this account. To resolve this error, reduce your request rate, or contact us at [email protected] to request a limit increase";
var messageWrapper = LimitExceededMessageWrapper.UnknownLimitExceeded;
var errMetadata = e?.Trailers.Get("err")?.Value;
if (errMetadata != null) {
messageWrapper = errMetadata switch
{
"topic_subscriptions_limit_exceeded" => LimitExceededMessageWrapper.TopicSubscriptionsLimitExceeded,
"operations_rate_limit_exceeded" => LimitExceededMessageWrapper.OperationsRateLimitExceeded,
"throughput_rate_limit_exceeded" => LimitExceededMessageWrapper.ThroughputRateLimitExceeded,
"request_size_limit_exceeded" => LimitExceededMessageWrapper.RequestSizeLimitExceeded,
"item_size_limit_exceeded" => LimitExceededMessageWrapper.ItemSizeLimitExceeded,
"element_size_limit_exceeded" => LimitExceededMessageWrapper.ElementSizeLimitExceeded,
_ => LimitExceededMessageWrapper.UnknownLimitExceeded,
};
} else {
var lowerCasedMessage = message.ToLower();
if (lowerCasedMessage.Contains("subscribers")) {
messageWrapper = LimitExceededMessageWrapper.TopicSubscriptionsLimitExceeded;
} else if (lowerCasedMessage.Contains("operations")) {
messageWrapper = LimitExceededMessageWrapper.OperationsRateLimitExceeded;
} else if (lowerCasedMessage.Contains("throughput")) {
messageWrapper = LimitExceededMessageWrapper.ThroughputRateLimitExceeded;
} else if (lowerCasedMessage.Contains("request limit")) {
messageWrapper = LimitExceededMessageWrapper.RequestSizeLimitExceeded;
} else if (lowerCasedMessage.Contains("item size")) {
messageWrapper = LimitExceededMessageWrapper.ItemSizeLimitExceeded;
} else if (lowerCasedMessage.Contains("element size")) {
messageWrapper = LimitExceededMessageWrapper.ElementSizeLimitExceeded;
} else {
messageWrapper = LimitExceededMessageWrapper.UnknownLimitExceeded;
}
}

return new LimitExceededException(messageWrapper, message, transportDetails, e);
}
}

/// <summary>
/// Provides a specific reason for the limit exceeded error.
/// </summary>
public static class LimitExceededMessageWrapper
{
/// <summary>
/// Topic subscriptions limit exceeded for this account.
/// </summary>
public static string TopicSubscriptionsLimitExceeded = "Topic subscriptions limit exceeded for this account";
/// <summary>
/// Request rate limit exceeded for this account.
/// </summary>
public static string OperationsRateLimitExceeded = "Request rate limit exceeded for this account";

/// <summary>
/// Bandwidth limit exceeded for this account.
/// </summary>
public static string ThroughputRateLimitExceeded = "Bandwidth limit exceeded for this account";
/// <summary>
/// Request size limit exceeded for this account.
/// </summary>
public static string RequestSizeLimitExceeded = "Request size limit exceeded for this account";
/// <summary>
/// Item size limit exceeded for this account.
/// </summary>
public static string ItemSizeLimitExceeded = "Item size limit exceeded for this account";
/// <summary>
/// Element size limit exceeded for this account.
/// </summary>
public static string ElementSizeLimitExceeded = "Element size limit exceeded for this account";
/// <summary>
/// Unknown limit exceeded for this account.
/// </summary>
public static string UnknownLimitExceeded = "Limit exceeded for this account";
}
Loading