Вопрос или проблема
В общем, мы обрабатываем исключения следующим образом в ~/bootstrap/app.php
->withExceptions(function (Exceptions $exceptions) {
$exceptions->respond(function (Response $response, $e, Request $request) {
if ($e instanceof ValidationException) {
return response()->json($e->errors(), Response::HTTP_UNPROCESSABLE_ENTITY);
} elseif ($e instanceof MethodNotAllowedHttpException) {
$result['errorMsg'] = 'Метод не разрешен.';
$result['body'] = ['requestedUrl' => $request->getUri()];
return response()->json($result, Response::HTTP_METHOD_NOT_ALLOWED);
} elseif ($e instanceof ModelNotFoundException || $e instanceof NotFoundHttpException || $e instanceof RouteNotFoundException) {
$result['errorMsg'] = $e->getMessage() ?? 'Запись не найдена.';
$result['body'] = ['requestedUrl' => $request->getUri()];
return response()->json($result, Response::HTTP_NOT_FOUND);
} elseif ($e instanceof AuthenticationException) {
$result['errorMsg'] = 'Неаутентифицирован';
$result['body'] = ['requestedUrl' => $request->getUri()];
return response()->json($result, Response::HTTP_UNAUTHORIZED);
} elseif ($e instanceof HttpException) {
return response()->json($e->getMessage(), $e->getStatusCode());
} else {
$result['errorMsg'] = 'Внутренняя ошибка сервера.';
$result['body'] = ['requestedUrl' => $request->getUri()];
$result['exception'] = $e->getMessage();
return response()->json($result, Response::HTTP_INTERNAL_SERVER_ERROR);
}
return $response;
});
Но я хочу обрабатывать по-другому в отдельном классе и переопределить ~/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php
public function renderable(callable $renderUsing)
{
Есть ли какой-либо способ, как мы можем обработать? Или настроить ответ?
Ответ или решение
Обработка Исключений в Laravel 11: Создание Кастомного Класса для API
В Laravel 11 обработка исключений является важным аспектом разработки API. Ваша задача состоит в том, чтобы организовать кастомную обработку ошибок в отдельном классе и переопределить стандартное поведение, предоставляемое в файле ~/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php
. Это позволяет более структурированно управлять исключениями и ответами API. В данном руководстве мы подробно рассмотрим, как это сделать.
Шаг 1: Создание Кастомного Обработчика Исключений
Для начала создайте новый класс для обработки исключений. Рекомендуется располагать его в директории app/Exceptions
. Например, можно назвать его ApiExceptionHandler.php
:
// app/Exceptions/ApiExceptionHandler.php
namespace App\Exceptions;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class ApiExceptionHandler
{
public function handle(Exception $e, Request $request): JsonResponse
{
if ($e instanceof ValidationException) {
return response()->json($e->errors(), JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
} elseif ($e instanceof MethodNotAllowedHttpException) {
return response()->json(['errorMsg' => 'Method not allowed.', 'body' => ['requestedUrl' => $request->getUri()]], JsonResponse::HTTP_METHOD_NOT_ALLOWED);
} elseif ($e instanceof NotFoundHttpException) {
return response()->json(['errorMsg' => 'Запись не найдена.', 'body' => ['requestedUrl' => $request->getUri()]], JsonResponse::HTTP_NOT_FOUND);
} elseif ($e instanceof AuthenticationException) {
return response()->json(['errorMsg' => 'Неаутентифицировано.', 'body' => ['requestedUrl' => $request->getUri()]], JsonResponse::HTTP_UNAUTHORIZED);
} else {
return response()->json(['errorMsg' => 'Внутренняя ошибка сервера.', 'body' => ['requestedUrl' => $request->getUri()], 'exception' => $e->getMessage()], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
}
}
}
Шаг 2: Регистрация Кастомного Обработчика
Теперь необходимо зарегистрировать ваш кастомный обработчик в Handler.php
. Откройте файл ~/app/Exceptions/Handler.php
:
// app/Exceptions/Handler.php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Request;
use Throwable;
class Handler extends ExceptionHandler
{
protected $apiExceptionHandler;
public function __construct()
{
$this->apiExceptionHandler = new ApiExceptionHandler();
parent::__construct();
}
public function render($request, Throwable $exception)
{
if ($request->is('api/*')) {
return $this->apiExceptionHandler->handle($exception, $request);
}
// Вызов родительского метода для других маршрутов
return parent::render($request, $exception);
}
}
В этом коде проверяется, является ли запрос API-запросом, и, если это так, используется ваш кастомный обработчик.
Шаг 3: Тестирование Кастомного Обработчика
Теперь, когда вы настроили свой обработчик, протестируйте его с помощью Postman или другого инструмента для тестирования API. Убедитесь, что все сценарии, такие как валидационные ошибки и ошибки аутентификации, обрабатываются правильно и возвращают ожидаемые JSON-ответы.
Заключение
Создание кастомного класса для обработки исключений в Laravel 11 позволяет организовать код и улучшить читаемость. Применение такого подхода к вашей архитектуре API помогает стандартизировать ответ и сделать обработку ошибок более эффективной. К тому же это дает вам возможность легко добавлять новые типы исключений в будущем, если это будет необходимо.
Таким образом, с помощью данной методики вы сможете оперативно и эфективно обрабатывать различные исключения в своем API с использованием Laravel 11.