Skip to content

Commit bd8c3c1

Browse files
committed
feature symfony#38354 [RateLimiter] add Limit::ensureAccepted() which throws RateLimitExceededException if not accepted (kbond)
This PR was merged into the 5.2-dev branch. Discussion ---------- [RateLimiter] add Limit::ensureAccepted() which throws RateLimitExceededException if not accepted | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Ref symfony#38241 (comment) | License | MIT | Doc PR | todo Example: ```php try { $limit = $limiter->consume()->ensureAccepted(); } catch (RateLimitExceededException $e) { $limit = $e->getLimit(); } ``` Commits ------- a7ecd0e [RateLimiter] add Limit::ensureAccepted() and RateLimitExceededException
2 parents 48adfb2 + a7ecd0e commit bd8c3c1

File tree

3 files changed

+103
-0
lines changed

3 files changed

+103
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\RateLimiter\Exception;
13+
14+
use Symfony\Component\RateLimiter\Limit;
15+
16+
/**
17+
* @author Kevin Bond <[email protected]>
18+
*
19+
* @experimental in 5.2
20+
*/
21+
class RateLimitExceededException extends \RuntimeException
22+
{
23+
private $limit;
24+
25+
public function __construct(Limit $limit, $code = 0, \Throwable $previous = null)
26+
{
27+
parent::__construct('Rate Limit Exceeded', $code, $previous);
28+
29+
$this->limit = $limit;
30+
}
31+
32+
public function getLimit(): Limit
33+
{
34+
return $this->limit;
35+
}
36+
37+
public function getRetryAfter(): \DateTimeImmutable
38+
{
39+
return $this->limit->getRetryAfter();
40+
}
41+
42+
public function getRemainingTokens(): int
43+
{
44+
return $this->limit->getRemainingTokens();
45+
}
46+
}

src/Symfony/Component/RateLimiter/Limit.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\RateLimiter;
1313

14+
use Symfony\Component\RateLimiter\Exception\RateLimitExceededException;
15+
1416
/**
1517
* @author Valentin Silvestre <[email protected]>
1618
*
@@ -34,6 +36,18 @@ public function isAccepted(): bool
3436
return $this->accepted;
3537
}
3638

39+
/**
40+
* @throws RateLimitExceededException if not accepted
41+
*/
42+
public function ensureAccepted(): self
43+
{
44+
if (!$this->accepted) {
45+
throw new RateLimitExceededException($this);
46+
}
47+
48+
return $this;
49+
}
50+
3751
public function getRetryAfter(): \DateTimeImmutable
3852
{
3953
return $this->retryAfter;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\RateLimiter\Tests;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\RateLimiter\Exception\RateLimitExceededException;
16+
use Symfony\Component\RateLimiter\Limit;
17+
18+
class LimitTest extends TestCase
19+
{
20+
public function testEnsureAcceptedDoesNotThrowExceptionIfAccepted()
21+
{
22+
$limit = new Limit(10, new \DateTimeImmutable(), true);
23+
24+
$this->assertSame($limit, $limit->ensureAccepted());
25+
}
26+
27+
public function testEnsureAcceptedThrowsRateLimitExceptionIfNotAccepted()
28+
{
29+
$limit = new Limit(10, $retryAfter = new \DateTimeImmutable(), false);
30+
31+
try {
32+
$limit->ensureAccepted();
33+
} catch (RateLimitExceededException $exception) {
34+
$this->assertSame($limit, $exception->getLimit());
35+
$this->assertSame(10, $exception->getRemainingTokens());
36+
$this->assertSame($retryAfter, $exception->getRetryAfter());
37+
38+
return;
39+
}
40+
41+
$this->fail('RateLimitExceededException not thrown.');
42+
}
43+
}

0 commit comments

Comments
 (0)