Laravel 11, Обработка исключений в пользовательском классе или исключениях для API.

Вопрос или проблема

В общем, мы обрабатываем исключения следующим образом в ~/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.

Оцените материал
Добавить комментарий

Капча загружается...