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.