Исключение ThrottleRequestsException
Исключение ThrottleRequestsException является частью механизма ограничения частоты запросов в Laravel. Оно возникает в ситуациях, когда количество запросов от одного клиента превышает установленный лимит за определённый временной интервал. Данное исключение выбрасывается автоматически middleware throttle или при использовании метода throttle в фасаде RateLimiter.
Исключение наследуется от TooManyRequestsHttpException и возвращает HTTP-статус 429. Первым параметром конструктора принимается количество секунд до сброса лимита, вторым - сообщение об ошибке, третьим - код исключения, четвёртым - предыдущее исключение.
Синтаксис
<?php
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
throw new TooManyRequestsHttpException($retryAfter, $message, $code, $previous);
?>
Пример
Давайте создадим маршрут с ограничением 5 запросов в минуту и обработаем исключение:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ApiController;
Route::middleware('throttle:5,1')->get('/api/data', [ApiController::class, 'index']);
?>
<?php
namespace App\Http\Controllers;
class ApiController extends Controller
{
public function index()
{
return ['status' => 'success', 'data' => ['a', 'b', 'c', 'd', 'e']];
}
}
?>
Результат выполнения после превышения лимита:
"Too Many Attempts. Please try again in 60 seconds."
Пример
Давайте перехватим исключение в обработчике и вернём кастомный ответ:
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
use Throwable;
class Handler extends ExceptionHandler
{
public function render($request, Throwable $e)
{
if ($e instanceof TooManyRequestsHttpException) {
return response()->json([
'error' => 'Too many requests',
'retry_after' => $e->getHeaders()['Retry-After'] ?? 60
], 429);
}
return parent::render($request, $e);
}
}
?>
Результат выполнения при превышении лимита:
{"error":"Too many requests","retry_after":60}
Пример
Давайте используем фасад RateLimiter для ручной проверки и генерации исключения:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\RateLimiter;
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
class UserController extends Controller
{
public function profile()
{
$key = 'profile-' . request()->ip();
if (RateLimiter::tooManyAttempts($key, 3)) {
$seconds = RateLimiter::availableIn($key);
throw new TooManyRequestsHttpException($seconds, 'Too many profile requests');
}
RateLimiter::hit($key, 60);
return ['user' => 'John Doe', 'email' => 'john@example.com'];
}
}
?>
Результат выполнения при превышении лимита:
"Too many profile requests"
Смотрите также
-
исключение
TooManyRequestsHttpException,
являющееся родительским классом -
исключение
HttpException,
базовое исключение для HTTP-ошибок -
исключение
AccessDeniedHttpException,
выбрасываемое при запрете доступа -
исключение
NotFoundHttpException,
выбрасываемое при отсутствии ресурса