Обработка ошибок
Что-то всегда идёт не так: статья не найдена, доступ запрещён, база недоступна. В Slim на любую такую ситуацию бросают исключение, а посредник ошибок, подключённый в config/middleware.php, превращает его в ответ с нужным кодом состояния.
Исключения HTTP
Для типовых ошибок в Slim есть готовые классы исключений. Одно из них уже используется в ShowPostAction:
// src/Action/ShowPostAction.php
use Slim\Exception\HttpNotFoundException;
$post = $this->posts->find((int) $args['id']);
if ($post === null) {
throw new HttpNotFoundException($request, 'Статья не найдена');
}Откройте /posts/999 — придёт ответ с кодом 404. Первым аргументом исключению передают запрос, вторым, необязательным, — сообщение.
| Исключение | Код | Когда бросать |
|---|---|---|
HttpBadRequestException | 400 | Запрос составлен неверно |
HttpUnauthorizedException | 401 | Нужен вход |
HttpForbiddenException | 403 | Входа недостаточно, доступ запрещён |
HttpNotFoundException | 404 | Записи или страницы нет |
HttpMethodNotAllowedException | 405 | Метод не подходит маршруту |
Все они лежат в пространстве имён Slim\Exception. Ошибки 404 для несуществующего адреса и 405 для неподходящего метода Slim бросает сам. Любое другое исключение — ошибка в коде или недоступная база — превращается в ответ с кодом 500.
Страница по умолчанию
При APP_DEBUG=true посредник показывает подробности: класс исключения, файл, строку и цепочку вызовов. При false — короткую страницу с названием ошибки. Она работает, но не похожа на остальной сайт.
Свой шаблон ошибки
Создайте отдельный шаблон. Он не наследует макет: обработчик ошибок работает снаружи остальных слоёв, и функции вроде url_for() в этот момент могут быть ещё не подключены.
{# templates/error.twig #}
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Ошибка {{ status }}</title>
</head>
<body>
<h1>{{ status == 404 ? 'Страница не найдена' : 'Что-то пошло не так' }}</h1>
<p><a href="/">На главную</a></p>
</body>
</html>Свой обработчик
Метод addErrorMiddleware() возвращает объект посредника. Ему задают функцию, которая будет формировать ответ вместо стандартной:
// config/middleware.php
use Psr\Http\Message\ServerRequestInterface;
use Slim\Exception\HttpException;
use Slim\Views\Twig;
$errorMiddleware = $app->addErrorMiddleware($settings['debug'], true, true);
if (!$settings['debug']) {
$errorMiddleware->setDefaultErrorHandler(
function (ServerRequestInterface $request, Throwable $exception) use ($app) {
$status = $exception instanceof HttpException ? $exception->getCode() : 500;
$response = $app->getResponseFactory()->createResponse($status);
return $app->getContainer()->get(Twig::class)
->render($response, 'error.twig', ['status' => $status]);
}
);
}У исключений HTTP код состояния возвращает getCode(); для всех остальных берётся 500. Свой обработчик включается только вне режима отладки — при разработке подробная страница Slim полезнее.
Поставьте в .env значение APP_DEBUG=false и откройте /posts/999 — появится ваша страница «Страница не найдена».
Частая ошибка
Режим отладки на рабочем сервере показывает посетителю пути к файлам, текст запросов SQL и фрагменты кода. Первый аргумент addErrorMiddleware() на сервере должен быть false, а узнавать об ошибках нужно из журнала — ему посвящён следующий урок. И не выводите в своём шаблоне текст $exception->getMessage() для ошибок 500: в нём бывают внутренние подробности.