Skip to content

Commit

Permalink
chore: improve resource exhausted error message (#584)
Browse files Browse the repository at this point in the history
* chore: improve resource exhausted error message

* remove unused imports

* make LimitExceededMessageWrapper a static class with static members instead

* create separate method CreateWithMessageWrapper
  • Loading branch information
anitarua authored Oct 31, 2024
1 parent 4d28ef7 commit 4a8b746
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 5 deletions.
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";
}

0 comments on commit 4a8b746

Please sign in to comment.