[RateLimiter] add Limit::ensureAccepted() and RateLimitExceededException

This commit is contained in:
Kevin Bond 2020-09-30 09:50:50 -04:00
parent f06f2f018e
commit a7ecd0ed08
No known key found for this signature in database
GPG Key ID: E58ACC1E3892C795
3 changed files with 103 additions and 0 deletions

View File

@ -0,0 +1,46 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\RateLimiter\Exception;
use Symfony\Component\RateLimiter\Limit;
/**
* @author Kevin Bond <kevinbond@gmail.com>
*
* @experimental in 5.2
*/
class RateLimitExceededException extends \RuntimeException
{
private $limit;
public function __construct(Limit $limit, $code = 0, \Throwable $previous = null)
{
parent::__construct('Rate Limit Exceeded', $code, $previous);
$this->limit = $limit;
}
public function getLimit(): Limit
{
return $this->limit;
}
public function getRetryAfter(): \DateTimeImmutable
{
return $this->limit->getRetryAfter();
}
public function getRemainingTokens(): int
{
return $this->limit->getRemainingTokens();
}
}

View File

@ -11,6 +11,8 @@
namespace Symfony\Component\RateLimiter;
use Symfony\Component\RateLimiter\Exception\RateLimitExceededException;
/**
* @author Valentin Silvestre <vsilvestre.pro@gmail.com>
*
@ -34,6 +36,18 @@ class Limit
return $this->accepted;
}
/**
* @throws RateLimitExceededException if not accepted
*/
public function ensureAccepted(): self
{
if (!$this->accepted) {
throw new RateLimitExceededException($this);
}
return $this;
}
public function getRetryAfter(): \DateTimeImmutable
{
return $this->retryAfter;

View File

@ -0,0 +1,43 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\RateLimiter\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\RateLimiter\Exception\RateLimitExceededException;
use Symfony\Component\RateLimiter\Limit;
class LimitTest extends TestCase
{
public function testEnsureAcceptedDoesNotThrowExceptionIfAccepted()
{
$limit = new Limit(10, new \DateTimeImmutable(), true);
$this->assertSame($limit, $limit->ensureAccepted());
}
public function testEnsureAcceptedThrowsRateLimitExceptionIfNotAccepted()
{
$limit = new Limit(10, $retryAfter = new \DateTimeImmutable(), false);
try {
$limit->ensureAccepted();
} catch (RateLimitExceededException $exception) {
$this->assertSame($limit, $exception->getLimit());
$this->assertSame(10, $exception->getRemainingTokens());
$this->assertSame($retryAfter, $exception->getRetryAfter());
return;
}
$this->fail('RateLimitExceededException not thrown.');
}
}