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 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
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 new LimitExceededException(ex.Message, transportDetails, ex);

case StatusCode.NotFound:
return new NotFoundException(ex.Message, transportDetails);
Expand Down
82 changes: 79 additions & 3 deletions src/Momento.Sdk/Exceptions/LimitExceededException.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,91 @@
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 message, MomentoErrorTransportDetails transportDetails, RpcException? e = null) : base(MomentoErrorCode.LIMIT_EXCEEDED_ERROR, message, transportDetails, e)
{
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 errMetadata = e?.Trailers.Get("err")?.Value;
if (errMetadata != null) {
this.MessageWrapper = errMetadata switch
{
"topic_subscriptions_limit_exceeded" => LimitExceededMessageWrapper.TopicSubscriptionsLimitExceeded.Value,
"operations_rate_limit_exceeded" => LimitExceededMessageWrapper.OperationsRateLimitExceeded.Value,
"throughput_rate_limit_exceeded" => LimitExceededMessageWrapper.ThroughputRateLimitExceeded.Value,
"request_size_limit_exceeded" => LimitExceededMessageWrapper.RequestSizeLimitExceeded.Value,
"item_size_limit_exceeded" => LimitExceededMessageWrapper.ItemSizeLimitExceeded.Value,
"element_size_limit_exceeded" => LimitExceededMessageWrapper.ElementSizeLimitExceeded.Value,
_ => LimitExceededMessageWrapper.UnknownLimitExceeded.Value,
};
} else {
var lowerCasedMessage = message.ToLower();
this.MessageWrapper = LimitExceededMessageWrapper.UnknownLimitExceeded.Value;
if (lowerCasedMessage.Contains("subscribers")) {
this.MessageWrapper = LimitExceededMessageWrapper.TopicSubscriptionsLimitExceeded.Value;
} else if (lowerCasedMessage.Contains("operations")) {
this.MessageWrapper = LimitExceededMessageWrapper.OperationsRateLimitExceeded.Value;
} else if (lowerCasedMessage.Contains("throughput")) {
this.MessageWrapper = LimitExceededMessageWrapper.ThroughputRateLimitExceeded.Value;
} else if (lowerCasedMessage.Contains("request limit")) {
this.MessageWrapper = LimitExceededMessageWrapper.RequestSizeLimitExceeded.Value;
} else if (lowerCasedMessage.Contains("item size")) {
this.MessageWrapper = LimitExceededMessageWrapper.ItemSizeLimitExceeded.Value;
} else if (lowerCasedMessage.Contains("element size")) {
this.MessageWrapper = LimitExceededMessageWrapper.ElementSizeLimitExceeded.Value;
} else {
this.MessageWrapper = LimitExceededMessageWrapper.UnknownLimitExceeded.Value;
}
}
}
}
anitarua marked this conversation as resolved.
Show resolved Hide resolved

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

/// <summary>
/// Bandwidth limit exceeded for this account.
/// </summary>
public static readonly LimitExceededMessageWrapper ThroughputRateLimitExceeded = new LimitExceededMessageWrapper("Bandwidth limit exceeded for this account");
/// <summary>
/// Request size limit exceeded for this account.
/// </summary>
public static readonly LimitExceededMessageWrapper RequestSizeLimitExceeded = new LimitExceededMessageWrapper("Request size limit exceeded for this account");
/// <summary>
/// Item size limit exceeded for this account.
/// </summary>
public static readonly LimitExceededMessageWrapper ItemSizeLimitExceeded = new LimitExceededMessageWrapper("Item size limit exceeded for this account");
/// <summary>
/// Element size limit exceeded for this account.
/// </summary>
public static readonly LimitExceededMessageWrapper ElementSizeLimitExceeded = new LimitExceededMessageWrapper("Element size limit exceeded for this account");
/// <summary>
/// Unknown limit exceeded for this account.
/// </summary>
public static readonly LimitExceededMessageWrapper UnknownLimitExceeded = new LimitExceededMessageWrapper("Limit exceeded for this account");

private LimitExceededMessageWrapper(string value)
{
Value = value;
}

/// <summary>
/// The value of the LimitExceededMessageWrapper.
/// </summary>
public string Value { get; private set; }
}
anitarua marked this conversation as resolved.
Show resolved Hide resolved
Loading