Обработка исключений
Настройка
config/exception.php
return [
// Здесь настраивается класс обработки исключений
'' => support\exception\Handler::class,
];
В режиме множественных приложений вы можете настраивать отдельный класс обработки исключений для каждого приложения, см. Множественные приложения.
Класс обработки исключений по умолчанию
В webman исключения по умолчанию обрабатываются классом support\exception\Handler
. Можно изменить класс обработки исключений по уумолчанию, изменив файл настроек config/exception.php
. Класс обработки исключений должен реализовывать интерфейс Webman\Exception\ExceptionHandlerInterface
.
interface ExceptionHandlerInterface
{
/**
* Запись журнала
* @param Throwable $e
* @return mixed
*/
public function report(Throwable $e);
/**
* Рендеринг ответа
* @param Request $request
* @param Throwable $e
* @return Response
*/
public function render(Request $request, Throwable $e) : Response;
}
Рендеринг ответа
Метод render
класса обработки исключений используется для рендеринга ответа.
Если значение debug
в файле настроек config/app.php
установлено как true
(далее app.debug=true
), будут возвращены подробные сведения об исключении, в противном случае - краткая информация об исключении.
Если запрос ожидает JSON-ответ, исключение будет возвращено в формате JSON, например:
{
"code": "500",
"msg": "Информация об исключении"
}
Если app.debug=true
, в JSON-данных будет также дополнительное поле trace
, содержащее подробный стек вызовов.
Вы можете создать собственный класс обработки исключений для изменения логики обработки исключений по умолчанию.
Бизнес-исключение BusinessException
Иногда мы хотим прервать выполнение запроса во вложенной функции и вернуть клиенту сообщение об ошибке, для этого можно использовать исключение BusinessException
.
Например:
<?php
namespace app\controller;
use support\Request;
use support\exception\BusinessException;
class FooController
{
public function index(Request $request)
{
$this->chackInpout($request->post());
return response('hello index');
}
protected function chackInpout($input)
{
if (!isset($input['token'])) {
throw new BusinessException('Ошибка параметра', 3000);
}
}
}
В этом примере будет возвращено
{"code": 3000, "msg": "Ошибка параметра"}
Примечание
Для бизнес-исключения BusinessException не требуется обработка в блоке try-catch, фреймворк будет автоматически обрабатывать и, в зависимости от типа запроса, возвращать соответствующий результат.
Пользовательское бизнес-исключение
Если указанный выше ответ не соответствует вашим требованиям, например, если вы хотите изменить msg
на message
, вы можете создать собственное исключение MyBusinessException
.
Создайте файл app/exception/MyBusinessException.php
с содержимым:
<?php
namespace app\exception;
use support\exception\BusinessException;
use Webman\Http\Request;
use Webman\Http\Response;
class MyBusinessException extends BusinessException
{
public function render(Request $request): ?Response
{
// JSON-запрос возвращает данные в формате JSON
if ($request->expectsJson()) {
return json(['code' => $this->getCode() ?: 500, 'message' => $this->getMessage()]);
}
// Если запрос не является JSON-ом, то возвращается страница
return new Response(200, [], $this->getMessage());
}
}
Теперь при вызове бизнес-исключения
use app\exception\MyBusinessException;
throw new MyBusinessException('Ошибка параметра', 3000);
в случае JSON-запроса будет получен JSON-ответ подобный следующему:
{"code": 3000, "message": "Ошибка параметра"}
Подсказка
Поскольку исключение BusinessException относится к бизнес-исключениям (например, неправильные входные параметры пользователя), которые можно предсказать, фреймворк не считает исключение фатальной ошибкой и не регистрирует его в журнале.
Вывод
В любом случае, когда требуется прервать текущий запрос и вернуть информацию клиенту, можно использовать исключение BusinessException
.