При запуске нового проект Imhotep, обработка ошибок и исключений полностью настроена. Класс App\Exceptions\Handler - регистрирует все ошибки и исключения созданные приложением и затем отображает их пользователю.
Параметр debug в конфигурационном файле config/app.php определяет, сколько информации об ошибке увидит пользователь. По умолчанию, параметр считывает значение из переменной окружения APP_DEBUG, который расположен в файле .env.
Во время локальной разработки, значение APP_DEBUG должно быть установлено как true. После того, как приложение будет полностью протестировано и готово к выкладке в продакшн, значение необходимо установить как false. Если в продакшене режим отладки останется включенным, существует огромный риск раскрыть конечным пользователям приложения конфиденциальные значения конфигурации.
Все исключения обрабатываются классом App\Exceptions\Handler. Данный класс содержит метод register, в котором можно зарегистрировать свои отчеты для исключений и замыкания отображения. Сейчас подробно рассмотрим эти концепции. Отчеты для исключения используются для регистрации исключений или отправки их во внешнюю службу мониторинга. По умолчанию, исключения регистрируются в соответствии заданной конфигурации логирования, однако, это можно легко изменить.
Например, необходимо по разному сообщать о разных типах исключений, для этого используя метод reportable зарегистрируйте замыкание, которое будет выполнено при наступлении данного исключения:
use App\Exceptions\InvalidOrderException;
public function register()
{
$this->reportable(function (InvalidOrderException $e) {
// ...
});
}
Когда регистрируется собственное замыкание, используя метод reportable, Imhotep будет по прежнему обрабатывать исключение, используя базовую конфигурацию. Если необходимо остановить распространение исключения в стек журнала по умолчанию, используйте метод stop, при определении замыкания или верните false из замыкания:
$this->reportable(function (InvalidOrderException $e) {
// ...
})->stop();
// или
$this->reportable(function (InvalidOrderException $e) {
return false;
});
При наличии авторизованного пользователя, Imhotep автоматически добавляет идентификатор текущего пользователя в каждое сообщение журнала ошибок в качестве контекстных данных. Для определения собственных глобальных контекстных данных, переопределите метод context класса App\Exceptions\Handler:
protected function context()
{
return array_merge(parent::context(), [
'foo' => 'bar',
]);
}
Иногда, может потребоваться добавить уникальный контекст для конкретного исключения. Определив метод context для конкретного исключения, можно будет указать любые данные, относящиеся к этому исключения, которые будут добавлены в запись журнала ошибок:
<?php
namespace App\Exceptions;
use Exception;
class InvalidOrderException extends Exception
{
// ...
public function context()
{
return ['order_id' => $this->orderId];
}
}
reportИногда, может потребоваться сообщить об исключении без завершения обработки текущего запроса. Помощник report позволяет быстро сообщить об исключении, не отображая страницу с ошибкой для пользователя:
public function isValid($value)
{
try {
// Проверка `$value` ...
} catch (Throwable $e) {
report($e);
return false;
}
}
Бывают исключения, которые необходимо всегда игнорировать и не сообщать о них. Для этого, обработчик исключения содержит свойство $dontReport. Добавив класс исключения в данный массив, он будет проигнорирован обработчиком, однако у него может быть собственная логика отображения:
use App\Exceptions\InvalidOrderException;
protected $dontReport = [
InvalidOrderException::class,
];
За кулисами Imhotep уже игнорирует для вас некоторые типы ошибок.
По умолчанию обработчик исключений будет преобразовывать исключения в стандартный HTTP-ответ. Однако можно зарегистрировать собственное замыкание для отображения исключений конкретного типа. Это можно сделать с помощью метода renderable:
use App\Exceptions\InvalidOrderException;
public function register()
{
$this->renderable(function (InvalidOrderException $e, $request) {
return response()->view('errors.invalid-order', [], 500);
});
}
Также, с помощью метода renderable, можно переопределить отображение встроенных исключений, например NotFoundHttpException. Если замыкание, переданное методу renderable не возвращает значения, будет использоваться отображение по умолчанию:
use Imhotep\Contracts\Http\NotFoundHttpException;
public function register()
{
$this->renderable(function (NotFoundHttpException $e, $request) {
if ($request->is('api/*')) {
return response()->json([
'message' => 'Record not found.'
], 404);
}
});
}
Для каждого исключения, можно создать собственные методы report и render, которые будут вызываться автоматически обработчиком ошибок. Это позволит уменьшить код внутри обработчика ошибок и разложить логику приложения:
<?php
namespace App\Exceptions;
use Exception;
class InvalidOrderException extends Exception
{
public function report()
{
// ...
}
public function render($request)
{
return response(...);
}
}
Если ваше исключение расширяет другое исключение, которое уже имеет метод render, например встроенные исключения Imhotep, можно вернуть false из метода render, для отображения ответа по умолчанию:
public function render($request)
{
// Определить, требуется ли для исключения пользовательское отображение...
if ($request->is('foo/bar')) {
// Собственное отображение ответа
}
return false;
}
Если ваше исключение содержит собственную логику отчетности, которая выполняется только по определенных условиях, то может потребоваться указать Imhotep, когда сообщать об исключении используя обработку по умолчанию. Для этого верните false из метода report:
public function report()
{
// Определить, требуется ли для исключения собственная отчетность ...
return false;
}
Некоторые исключения описывают коды HTTP-ошибок. Например, это может быть ошибка «page not found» (404), «unauthorized error» (401) или даже ошибка 500, сгенерированная разработчиком. Чтобы создать такой ответ из любой точки приложения, используйте глобальный помощник abort:
abort(404);
Imhotep позволяет легко отображать собственные страницы ошибок для различных кодов HTTP-ошибок. Например, для HTTP-ошибки с кодом 404, создайте файл resources/views/errors/404.moon.php. Этот шаблон будет отображаться для всех ошибок с кодом 404. Шаблона в этом каталоге должны называться в соответствии с кодом HTTP-ошибки, которому оно соответствует. Экземпляр Imhotep\Contracts\Http\HttpException, вызванный помощником abort, будет передан в шаблон как переменная $exception:
<h2>{{ $exception->getMessage() }}</h2>