-
Notifications
You must be signed in to change notification settings - Fork 73
feat: enhance RateLimitException to return extra information #426
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
base: master
Are you sure you want to change the base?
Conversation
private final String configurationName; | ||
|
||
public RateLimitException(Long retryAfterNanoSeconds, Long remainingTokens, String configurationName) { | ||
super("Rate limit exceeded for configuration: " + configurationName + ". Retry after: " + (retryAfterNanoSeconds != null ? retryAfterNanoSeconds : 0) + "ns. Remaining tokens: " + (remainingTokens != null ? remainingTokens : 0)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not quite sure about it but can the remainingTokens be greater than 0?
Nanoseconds are hard to read. What about milliseconds? Or seconds?
The message line is a little bit to long. my suggestion:
super("Rate limit exceeded for configuration: " + configurationName + ". " +
"Retry after: " + toMilliseconds(retryAfterNanoSeconds) + "ns. " +
"Remaining tokens: " + toMilliseconds(remainingTokens));
// the slower variant
super("Rate limit exceeded for configuration %s : . Retry after: %sms . Remaining tokens: %s".formatted(
configurationName,
toMilliseconds(retryAfterNanoSeconds),
toMilliseconds(remainingTokens))
);
private static long toMilliseconds(Long retryAfterNanoSeconds) {
return retryAfterNanoSeconds != null ? TimeUnit.NANOSECONDS.toMillis(retryAfterNanoSeconds) : 0;
}
* This exception is thrown when the rate limit is reached in the context of a method level when using the | ||
* {@link RateLimiting} annotation. | ||
*/ | ||
public class RateLimitException extends RuntimeException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use Lomboks @Getter
RateLimitException ex1 = assertThrows(RateLimitException.class, () -> testService.withCacheKey("key1")); | ||
assertTrue(ex1.getRetryAfterNanoSeconds() >= 0); | ||
assertTrue(ex1.getRemainingTokens() >= 0); | ||
assertNotNull(ex1.getConfigurationName()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assertEquals("default", ex1.getConfigurationName());
private final long remainingTokens; | ||
private final String configurationName; | ||
|
||
public RateLimitException(Long retryAfterNanoSeconds, Long remainingTokens, String configurationName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the cacheKey also of interest?
Currently the RateLimitException raises an empty exception. The PR aims to modify the exception to add extra values which can then by the SDK/lib consumers to retreive more information from the given exception and also open up room for better handling of exceptions from Annotation
@RateLimiting
Exception handling improvements:
retryAfterNanoSeconds
,remainingTokens
, andconfigurationName
) and corresponding constructor/getters to theRateLimitException
class to provide more context when a rate limit is exceeded.RateLimitAspect
to capture and log the retry time (retryAfterNanoSeconds
) when a limit is hit, and to pass this value along with remaining tokens to the result object.