-
Notifications
You must be signed in to change notification settings - Fork 11.4k
RateLimiter is triggered when callback function returns empty string #55084
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
Comments
Any value returned from the callback, including framework/src/Illuminate/Cache/RateLimiter.php Lines 105 to 118 in 6728659
The The only case a hit is prevented, is if the If the code passes that condition, in other words, every time the callback is called, unless the callback throws an exception, the rate limiter gets a hit, regardless of the callback's return value. |
Yes, but if the result of the callback is an empty string, is_null will do nothing because empty string is not null. Therefore $result will be empty string and the return of the tap function will be an empty string. The negation of an empty string is true so ! $executed is triggered … |
And what does it have to do with hitting or not the rate limiter? Is From your original post, I understood you wanted to prevent the rate limiter to get a hit, and assumed that returning What happens is that, unless the callback throws an exception, if the callback is called, its return value has no deal on preventing the rate limiter to get a hit. If your callback returns:
And for any other value returned, the rate limiter gets a hit. The reasoning on why the return value from the callback is preserved is laid on this PR #45611 Originally, it always returned |
I see, you are talking about the sample in the docs: use Illuminate\Support\Facades\RateLimiter;
$executed = RateLimiter::attempt(
'send-message:'.$user->id,
$perMinute = 5,
function() {
// Send message...
}
);
if (! $executed) {
return 'Too many messages sent!';
} https://laravel.com/docs/12.x/rate-limiting#basic-usage In the case the callback returns a falsy value, the check for the callback being executed should be: if ($executed === false) {
return 'Too many messages sent!';
} That can also be misleading if the callback returns Not sure what is the best solution here, if it is to make the docs clear about this, or to send a PR restoring the behavior before PR #45611, or to propose an alternative solution. Please excuse the misunderstanding. Although the callback's return still has no impact on if the rate limiter gets a hit or nor, I now understand better your point. |
Laravel Version
11.23.5
PHP Version
8.2.28
Database Driver & Version
Mysql 8.4.3
Description
When the callback function returns an empty string the RateLimiter is triggered after the first attempt.
This is due to the following code inside cache/RateLimiter.php
if (is_null($result = $callback())) {
$result = true;
}
is_null() should be replaced with empty() to allow return of empty string.
Steps To Reproduce
The ratelimiter is triggered immediately when the function returns an empty string
$executed = RateLimiter::attempt(
'contact-search-'.Auth::user()->id,
$perMinute = 15,
function() use($request){
$data = $this->contactSearch($request);
return $data;
},
$decayRate = 600
);
The text was updated successfully, but these errors were encountered: