Обробка помилок

← Обробка помилок

Ashterix

docs: rewrite JsonRpcBundle docs, add SDK docs, move them under docs/api

uk/docs/api/rest-bundle/error_handling.md новий файл +94 −0

Обробка помилок

Формат

Кожна помилка REST-виклику чи документа повертається як документ RFC 9457 (problem details) з HTTP-статусом помилки:

{
    "_error_object_standard": "RFC 9457",
    "status": 400,
    "type": "about:blank",
    "instance": "/rest/catalog/items/42",
    "title": "Ufo\\RestBundle\\Exceptions\\RestBadRequestException",
    "detail": "Invalid Data for call method: catalog.update",
    "detail-data": {
        "title": ["This value is too short. It should have 3 characters or more."]
    }
}
Поле Значення
status HTTP-статус, той самий, що й статус відповіді
type завжди about:blank
instance шлях запиту
title клас REST-винятку
detail повідомлення помилки
detail-data лише якщо RPC-помилка містить масив даних: повідомлення по параметрах для помилок валідації й типів

Трейси в документ не потрапляють.

Як вибирається статус

Ядро RPC перетворює будь-який виняток методу на RPC-помилку (подія rpc.error): винятки пакета ufo-tech/rpc-exceptions зберігають клас і код, TypeError аргументу стає помилкою параметра, інші винятки обгортаються (Обробка помилок у JsonRpcBundle). REST-шар відтворює виняток з RPC-помилки й перетворює його класом RestErrorNormalizer:

RPC-виняток REST-виняток Статус
RpcJsonParseException RestBadRequestException 400
RpcMethodNotFoundExceptionRpc RestResourceNotFoundException 404
ConstraintsImposedException RestValidationException 422
RpcBadParamException (помилки валідації й типів параметрів) RestBadRequestException 400
RpcBadRequestException RestBadRequestException 400
RpcInternalException, RpcRuntimeException RestInternalServerErrorException 500
RpcLogicException RestBadRequestException 400
RpcTokenNotSentException, RpcInvalidTokenException RestUnauthorizedException 401
RpcDataNotFoundException RestResourceNotFoundException 404
CustomApplicationException RestApplicationException код винятку, якщо це HTTP-код помилки, інакше 400
будь-який інший RestBadRequestException код винятку, якщо це HTTP-код помилки, інакше 400

Таблиця перевіряється згори донизу через instanceof, тому підкласи стоять перед батьківськими класами. HTTP-кодом помилки вважається код із переліку RestErrorNormalizer::REST_ERROR_CODES (стандартні коди 4xx і 5xx). Якщо такий код має виняток із будь-якого рядка таблиці, статус береться з нього.

Рядки 404 для RpcMethodNotFoundExceptionRpc, 422 для ConstraintsImposedException і збереження HTTP-коду прикладної помилки — з версії 1.3. У 1.0–1.2 ці випадки повертали 400. Див. Виправлені помилки.

Помилки REST-шару

Ситуація Виняток Статус
немає REST-маршруту для шляху, невідома версія, метод іншої групи RestResourceNotFoundException 404
HTTP-метод не дозволено для маршруту RestResourceNotAllowedException 405
некоректне або скалярне JSON-тіло RestBadRequestException 400
токен не передано або він недійсний RestUnauthorizedException 401

Як повернути потрібний статус з методу

Киньте RPC-виняток з таблиці або виняток з HTTP-кодом:

use Ufo\RpcError\CustomApplicationException;
use Ufo\RpcError\RpcDataNotFoundException;

/**
 * @throws RpcDataNotFoundException
 * @throws CustomApplicationException
 */
#[Route('/items/{id}', name: 'item', methods: ['GET'])]
public function item(int $id): array
{
    $item = $this->repository->find($id) ?? throw new RpcDataNotFoundException('Item is not found'); // 404
    if ($item->isClosed()) {
        throw new CustomApplicationException('Item is closed', 409);                              // 409
    }
    return $item->toArray();
}

Через JSON-RPC ті самі винятки дають звичайні RPC-помилки, тож один метод обслуговує обидва протоколи. Теги @throws додають ці статуси в документацію OpenAPI.

Примітки:

  • Виняток із кодом 0 стає внутрішньою RPC-помилкою і повертає 500.
  • Помилки валідації ядра RPC (#[RPC\Assertions], типи параметрів) повертають 400 з detail-data. 422 застосовується лише до ConstraintsImposedException, що доходить до REST-шару напряму.
  • Невідомий метод чи шлях — 404, але неправильний HTTP-метод для наявного шляху — 405.