You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using the HasRateLimits trait on a Request class (rather than a Connector), and configuring getTooManyAttemptsLimiter() with ->sleep(), a fatal error occurs when a 429 response is received.
The error happens at line 102 of HasRateLimits.php where $this->send() is called, but send() only exists on the Connector class, not on Request.
Why I Need Rate Limiting on Request
I need to define rate limits at the Request level because:
Different endpoints have different rate limits - Each API endpoint has its own rate/burst values
handleTooManyAttempts() uses request-specific data - When a 429 occurs, I calculate the wait time based on properties defined on the request (e.g., $rate, $burst)
// Each request has its own rate limit configurationclass GetOrderItems extends AbstractRequest
{
protectedfloat$rate = 0.5; // 0.5 requests/secondprotectedint$burst = 30; // Burst of 30protectedfunctionhandleTooManyAttempts(Response$response, Limit$limit): void
{
if ($response->status() !== 429) {
return;
}
// Calculate wait time based on THIS request's rate/burst$secondsNeeded = (int) ceil($this->burst / $this->rate);
$limit->exceeded(releaseInSeconds: $secondsNeeded);
}
}
Moving the trait to the Connector would lose this per-request context.
Steps to Reproduce
Add HasRateLimits trait to a Request class
Override getTooManyAttemptsLimiter() with ->sleep() enabled
When a 429 response is received and ->sleep() is enabled, Saloon should wait and retry the request automatically.
Actual Behavior
Warning
Error: Call to undefined method MyRequest::send() at vendor/saloonphp/rate-limit-plugin/src/Traits/HasRateLimits.php:102
Root Cause
In HasRateLimits.php lines 94-102:
if (isset($limitThatWasExceeded)) {
if (! $limit->getShouldSleep()) {
$this->throwLimitException($limitThatWasExceeded);
}
// This line fails when trait is on Requestreturn$this->send($response->getRequest());
}
When wasManuallyExceeded() is true and sleep() is enabled, the code calls $this->send() to retry. This works when the trait is on a Connector (which has send()), but fails when the trait is on a Request.
Description
When using the
HasRateLimitstrait on a Request class (rather than a Connector), and configuringgetTooManyAttemptsLimiter()with->sleep(), a fatal error occurs when a 429 response is received.The error happens at line 102 of
HasRateLimits.phpwhere$this->send()is called, butsend()only exists on the Connector class, not on Request.Why I Need Rate Limiting on Request
I need to define rate limits at the Request level because:
handleTooManyAttempts()uses request-specific data - When a 429 occurs, I calculate the wait time based on properties defined on the request (e.g.,$rate,$burst)Moving the trait to the Connector would lose this per-request context.
Steps to Reproduce
Minimal Example
Expected Behavior
When a 429 response is received and ->sleep() is enabled, Saloon should wait and retry the request automatically.
Actual Behavior
Warning
Error: Call to undefined method MyRequest::send() at vendor/saloonphp/rate-limit-plugin/src/Traits/HasRateLimits.php:102
Root Cause
In HasRateLimits.php lines 94-102:
When wasManuallyExceeded() is true and sleep() is enabled, the code calls $this->send() to retry. This works when the trait is on a Connector (which has send()), but fails when the trait is on a Request.
Environment