Laravel API, как правильно обрабатывать ошибки - PullRequest
0 голосов
/ 27 июня 2018

Кто-нибудь знает, как лучше всего обрабатывать ошибки в Laravel, есть какие-то правила или что-то соблюдать?

В настоящее время я делаю это:

public function store(Request $request)
{
  $plate = Plate::create($request->all());

  if ($plate) {
    return $this->response($this->plateTransformer->transform($plate));
  } else {
    // Error handling ?
    // Error 400 bad request
    $this->setStatusCode(400);
    return $this->responseWithError("Store failed.");
  }
}

И setStatusCode и responseWithError происходят от отца моего контроллера:

public function setStatusCode($statusCode)
{
    $this->statusCode = $statusCode;

    return $this;
}

public function responseWithError ($message )
{
    return $this->response([
        'error' => [
            'message' => $message,
            'status_code' => $this->getStatusCode()
        ]
    ]);

}

Но разве это хороший способ обработки ошибок API, я вижу другой способ обработки ошибок в Интернете, что лучше?

Спасибо.

Ответы [ 4 ]

0 голосов
/ 14 декабря 2018

Laravel уже может управлять ответами json по умолчанию.

Без настройки метода рендеринга в app \ Handler.php вы можете просто сгенерировать Symfony \ Component \ HttpKernel \ Exception \ HttpException, обработчик по умолчанию распознает, если заголовок запроса содержит Accept: application / json и распечатает сообщение об ошибке json соответственно.

Если включен режим отладки, он также выведет трассировку стека в формате json.

Вот краткий пример:

<?php

...

use Symfony\Component\HttpKernel\Exception\HttpException;

class ApiController
{
    public function myAction(Request $request)
    {
        try {
            // My code...
        } catch (\Exception $e) {
            throw new HttpException(500, $e->getMessage());
        }

        return $myObject;
    }
}

Вот ответ laravel с отключенной отладкой

{
    "message": "My custom error"
}

А вот ответ с отладкой на

{
    "message": "My custom error",
    "exception": "Symfony\\Component\\HttpKernel\\Exception\\HttpException",
    "file": "D:\\www\\myproject\\app\\Http\\Controllers\\ApiController.php",
    "line": 24,
    "trace": [
        {
            "file": "D:\\www\\myproject\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\ControllerDispatcher.php",
            "line": 48,
            "function": "myAction",
            "class": "App\\Http\\Controllers\\ApiController",
            "type": "->"
        },
        {
            "file": "D:\\www\\myproject\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php",
            "line": 212,
            "function": "dispatch",
            "class": "Illuminate\\Routing\\ControllerDispatcher",
            "type": "->"
        },

        ...
    ]
}

Используя HttpException, вызов возвратит код состояния http по вашему выбору (в данном случае внутренняя ошибка сервера 500)

0 голосов
/ 27 июня 2018

Попробуйте, я использовал его в своем проекте (app / Exceptions / Handler.php)

public function render($request, Exception $exception)
{
    if ($request->wantsJson()) {   //add Accept: application/json in request
        return $this->handleApiException($request, $exception);
    } else {
        $retval = parent::render($request, $exception);
    }

    return $retval;
}

Теперь обработайте исключение API

private function handleApiException($request, Exception $exception)
{
    $exception = $this->prepareException($exception);

    if ($exception instanceof \Illuminate\Http\Exception\HttpResponseException) {
        $exception = $exception->getResponse();
    }

    if ($exception instanceof \Illuminate\Auth\AuthenticationException) {
        $exception = $this->unauthenticated($request, $exception);
    }

    if ($exception instanceof \Illuminate\Validation\ValidationException) {
        $exception = $this->convertValidationExceptionToResponse($exception, $request);
    }

    return $this->customApiResponse($exception);
}

После этого пользовательский ответ обработчика Api

private function customApiResponse($exception)
{
    if (method_exists($exception, 'getStatusCode')) {
        $statusCode = $exception->getStatusCode();
    } else {
        $statusCode = 500;
    }

    $response = [];

    switch ($statusCode) {
        case 401:
            $response['message'] = 'Unauthorized';
            break;
        case 403:
            $response['message'] = 'Forbidden';
            break;
        case 404:
            $response['message'] = 'Not Found';
            break;
        case 405:
            $response['message'] = 'Method Not Allowed';
            break;
        case 422:
            $response['message'] = $exception->original['message'];
            $response['errors'] = $exception->original['errors'];
            break;
        default:
            $response['message'] = ($statusCode == 500) ? 'Whoops, looks like something went wrong' : $exception->getMessage();
            break;
    }

    if (config('app.debug')) {
        $response['trace'] = $exception->getTrace();
        $response['code'] = $exception->getCode();
    }

    $response['status'] = $statusCode;

    return response()->json($response, $statusCode);
}

Всегда добавляйте Accept: application/json в запросе API или JSON.

0 голосов
/ 28 июня 2018

По-моему, я бы сказал проще.

Возвращает ответ с кодом ошибки HTTP и пользовательским сообщением.

return response()->json(['error' => 'You need to add a card first'], 500);

Или, если вы хотите сгенерировать обнаруженную ошибку, вы можете сделать:

   try {
     // some code
    } catch (Exception $e) {
        return response()->json(['error' => $e->getMessage()], 500);
    }

Вы даже можете использовать это для отправки успешных ответов:

return response()->json(['activeSubscription' => $this->getActiveSubscription()], 200);

Таким образом, независимо от того, какая служба использует ваш API, она может ожидать получения одинаковых ответов на те же запросы.

Вы также можете увидеть, насколько гибко вы можете это сделать, передав код состояния HTTP.

0 голосов
/ 27 июня 2018

Хороший способ обработки ошибок Api - обработка этих ошибок в app \ Exceptions \ Hendler.php в методе рендеринга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...