Формат помилок в RPC

Формат помилок в RPC

Відповідно до специфікації JSON-RPC, коли виклик RPC призводить до помилки, об'єкт відповіді повинен містити елемент "error", який є об'єктом з наступними членами:

  • code: Число, яке вказує на тип помилки, що виникла. Це має бути ціле число.
  • message: Рядок, що надає короткий опис помилки. Повідомлення має бути коротким і лаконічним.
  • data (необов'язковий): Додаткова інформація про помилку, яка може бути корисною для налагодження.

Докладніше про формат помилок можна прочитати у специфікації JSON-RPC: JSON-RPC 2.0 Specification.

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

У JsonRpcBundle реалізовано стандартний механізм обробки помилок для RPC запитів, який базується на окремому пакеті ufo-tech/rpc-exceptions. Цей пакет надає можливість детально обробляти помилки, що виникають під час виконання RPC запитів, і повертати стандартизовані коди та повідомлення про помилки.

Коди помилок та їх інтерпретація

Пакет ufo-tech/rpc-exceptions надає перелік стандартних кодів помилок та відповідних класів виключень:

Код Клас Опис
-32700 RpcJsonParseException Сервер отримав недійсний JSON
-32600 RpcBadRequestException Недійсний об'єкт запиту (зокрема jsonrpc ≠ "2.0", порожній batch, вимкнений batch)
-32601 RpcMethodNotFoundExceptionRpc Метод не існує або недоступний у цій групі / версії API
-32602 RpcBadParamException, ConstraintsImposedException Недійсні параметри методу
-32603 RpcInternalException Внутрішня помилка JSON-RPC
-32500 RpcRuntimeException Помилка виконання процедури
-32400 RpcLogicException Логічна помилка в застосунку (наприклад, метод заблоковано #[RPC\Lock])
-32401 RpcTokenNotSentException Токен не передано (HTTP 401)
-32403 RpcInvalidTokenException Недійсний токен
-32404 RpcDataNotFoundException Дані не знайдено
-32300 RpcAsyncRequestException Помилка асинхронного запиту
-32301 RpcInvalidBatchRequestExceptions Помилка batch-запиту
-32000 RpcCustomServerException Серверна помилка, визначена реалізацією

Коди поза діапазоном -32768…-32000 перетворюються на CustomApplicationException, тож застосунок може використовувати власні коди помилок.

Помилки параметрів

Відсутні обов'язкові параметри, неправильні типи, невдале створення DTO та порушення #[RPC\Assertions] повертаються однією помилкою -32602 з повідомленнями по кожному параметру в error.data:

{
    "jsonrpc": "2.0",
    "id": 1,
    "error": {
        "code": -32602,
        "message": "Invalid Data for call method: user.create",
        "data": {"email": "Required parameter \"email\" not passed"}
    }
}

Помилки в документації

Винятки, оголошені в докблоці методу тегом @throws, потрапляють у документацію з кодом і повідомленням — клієнт заздалегідь знає, яких помилок чекати.

Використання виключень у вашому коді

Отримання об'єкта виключення з коду

use Ufo\RpcError\AbstractRpcErrorException;  
  
$code = -32700;  
$message = 'Some custom error message from rpc server'; // опціонально  
$rpcException = AbstractRpcErrorException::fromCode($code);  
// повертає екземпляр RpcJsonParseException::class

Отримання об'єкта виключення з масиву

use Ufo\RpcError\AbstractRpcErrorException;  
  
$data = [  
    'code' => -32600,  
    'message' => 'Some custom error message from rpc server',  
];  
$rpcException = AbstractRpcErrorException::fromArray($data);  
// повертає екземпляр RpcBadRequestException::class

Отримання об'єкта виключення з JSON

use Ufo\RpcError\AbstractRpcErrorException;  
  
$data = "{\"code\":-32500,\"message\":\"Some custom error message from rpc server\"}";  
$rpcException = AbstractRpcErrorException::fromJson($data);  
// повертає екземпляр RpcRuntimeException::class

Поради для розробників

Якщо ви, як розробник, хочете повертати специфічну помилку, яка буде інтерпретована RPC сервером, вам слід використовувати один з інтерфейсів, наданих пакетом ufo-tech/rpc-exceptions, або наслідувати типове виключення та притримуватися нумерації помилок.

Однак, якщо специфічна обробка не потрібна, сервер здатний обробити будь-яку помилку або виключення, що відбуваються на рівні виконання методу API, забезпечуючи стабільність та надійність вашої системи.

Додаткові дані помилки можна передати клієнту через error.data: усі винятки пакета (AbstractRpcErrorException реалізує Ufo\RpcError\IExceptionWithData) мають методи changeExtraData() / pushToExtraData(). Підмінити або доповнити помилку глобально можна в лістенері події rpc.error.