Ошибки и повторы
Ошибка приходит с HTTP-кодом и телом в JSON:
{ "error": { "code": "invalid_authorization", "message": "invalid authorization: chain 1, expected 11155111" } }code стабилен — ветвитесь по нему. message — для людей и может меняться.
| HTTP | code | Что значит | Что делать |
|---|---|---|---|
| 400 | invalid_json | Тело не JSON, в нём неизвестные поля или оно больше 64 КиБ. | Исправьте запрос. |
| 400 | invalid_query | Параметр запроса списка не подходит; какой — в message. | Исправьте параметр. |
| 401 | unauthorized | Нет API-ключа, он неизвестен или отозван. | Проверьте ключ и окружение: тестовый ключ работает только с API тестнетов. |
| 403 | partner_disabled | Ваш аккаунт отключён. | Напишите в поддержку. |
| 404 | not_found | Нет такого задания или снятия у вашего аккаунта, или вебхук не задан. | Проверьте id. |
| 409 | hot_wallet_not_active | Делегат горячего кошелька (котла) ещё разворачивается или не развернулся. | Дождитесь hot_wallet.active; после failed повторите POST /v1/hot-wallets. |
| 422 | unknown_chain | Сеть не поддерживается в этом окружении. | Используйте сеть окружения. |
| 422 | unknown_hot_wallet | Горячий кошелёк не зарегистрирован в этой сети. | Зарегистрируйте его через POST /v1/hot-wallets. |
| 422 | unknown_token | Токена нет в списке сети. | Укажите тикер из списка, его адрес или native. |
| 422 | invalid_address | Адрес — не ненулевой 0x-адрес. | Исправьте адрес. |
| 422 | invalid_amount | Сумма — не положительное целое в минимальных единицах. | Передайте строку из цифр или уберите amount, чтобы смести всё. |
| 422 | invalid_external_id | external_id длиннее 128 символов. | Сократите id. |
| 422 | invalid_authorization | Авторизация для другой сети или другого делегата, подписана не депозитным адресом или подпись неверна. | См. ниже. |
| 422 | invalid_url | Адрес вебхука — не публичный https. | Укажите публичный адрес по https. |
| 500 | internal | Сбой на нашей стороне. | Повторите позже с тем же external_id. |
У отключённого аккаунта то, что уже ушло в сеть, доводится до итога. Задания на sweep, снятия и развёртывания в очереди ждут и продолжатся, когда аккаунт снова включат. Вебхуки продолжают приходить.
invalid_authorization
Заголовок раздела «invalid_authorization»message начинается с | Причина |
|---|---|
invalid authorization: chain … | Подпись для другой сети или для сети 0. |
invalid authorization: delegates to … | Подписан не делегат этого горячего кошелька (для снятия — не нулевой адрес). |
invalid authorization: signature … | Верхний s или r, s вне допустимого диапазона. |
signed by … | Подписал другой ключ: не тот ключ, неверный y_parity или неверный хэш. |
authorization is required … | Снятие делегации пришло без авторизации. |
| что-то другое | Поле в неверном формате: address, y_parity, r или s. |
Подробнее — в гайде Подпись авторизаций.
Итог задания — не ошибка запроса
Заголовок раздела «Итог задания — не ошибка запроса»Принятый запрос всё ещё может закончиться неудачей: задание rejected до отправки или failed в сети — с причиной в
reason, горячий кошелёк, делегат которого не развернулся, — с причиной в error. Это приходит вебхуком и видно в
GET /v1/sweeps/{id}. Как и code, это стабильные коды — например, not_upgraded или insufficient_gas_balance, —
а не сообщения самой ноды: все они — в Статусах, подтверждениях и реоргах.
Повторы
Заголовок раздела «Повторы»- Повторяйте сетевые ошибки, таймауты и
5xx— с растущей паузой и тем жеexternal_id, чтобы задание не попало в очередь дважды: см. Идемпотентность. - Не повторяйте
4xxкак есть: тот же запрос получит тот же ответ. Исключение —409 hot_wallet_not_active: он пройдёт, когда делегат развернётся.
Ошибки API — это *portuna.Error с полями StatusCode, Code и Message; portuna.ErrorCode(err) возвращает
код или "" для других ошибок, например сетевых.
_, _, err := client.CreateSweep(ctx, req)switch portuna.ErrorCode(err) {case "": if err != nil { // network error or timeout: retry with the same ExternalID }case "invalid_authorization": // sign againcase "hot_wallet_not_active": // wait for hot_wallet.activedefault: // fix the request}Ошибки API — это ApiError с полями status, code и message. Другие ошибки, например сетевые, — нет.
import { ApiError } from '@portuna/sdk'
try { await client.createSweep(request)} catch (err) { if (err instanceof ApiError && err.code === 'invalid_authorization') { // sign again } else if (!(err instanceof ApiError) || err.status >= 500) { // retry with the same external_id } else { throw err }}