AACSearch / руководство
Ошибки и повторные запросы
Тело ответа с ошибкой, все коды статуса API тенанта, какие ошибки стоит повторять и как Idempotency-Key защищает повторную запись.
Любой ответ API тенанта (/v1) с кодом вне 2xx содержит JSON с понятным
человеку полем message. Решения принимайте по HTTP-статусу, а не по тексту:
сообщение предназначено для логов и людей и может меняться.
Тело ошибки
Формы две, в зависимости от того, какой слой отклонил запрос.
Шлюз и операции поискового движка. Проверки аутентификации, области ключа,
тарифа, квоты и лимитов выполняются перед любой операцией. Операции, которые
передаются поисковому движку (коллекции, документы, searchCollection,
multiSearch, …), отвечают в той же простой форме:
{ "message": "Forbidden - this API key may not access the collection \"orders\"." }Некоторые из них добавляют поля рядом с message:
| Статус | Дополнительные поля |
|---|---|
402, организация приостановлена | reason: "payment" (не прошла оплата подписки) или "manual" (владелец приостановил API) |
403, функции нет в тарифе | feature (например, "experiments"), plan (текущий тариф организации) |
429, месячная квота исчерпана | resets_at (Unix, миллисекунды) |
Операции, которые реализует сама контрольная плоскость. Это события, рекомендации, подсказки, эксперименты, коннекторы, ассистенты, голос, медиа, семантический поиск и поиск по изображению. Они отвечают с несколькими дополнительными полями:
{
"defined": false,
"code": "CONFLICT",
"status": 409,
"message": "The experiment is already running.",
"data": {}
}code — стабильное имя статуса (BAD_REQUEST, UNAUTHORIZED,
PAYMENT_REQUIRED, FORBIDDEN, NOT_FOUND, CONFLICT, TOO_MANY_REQUESTS,
INTERNAL_SERVER_ERROR). В data лежат подробности, если они есть:
| Случай | data |
|---|---|
Запрос не прошёл проверку схемы (400, сообщение Input validation failed) | issues: по записи на каждое неверное поле |
Кошелёк не покрывает AI-операцию (402) | available, requested: кредиты |
Поисковый ключ исчерпал лимит AI-операций на сессию (429) | retry_after: секунды |
Контракт описывает общую часть: message (схема ApiResponse), а для 402
ещё available / requested (схема InsufficientCredits). Клиент, читающий
message, работает с обеими формами. Числа сначала берите из
data.available, затем, если его нет, из available верхнего уровня.
Коды статуса
| Статус | Когда | Повторять? |
|---|---|---|
400 | Неверное тело или параметры запроса (Input validation failed), тело запроса не является корректным JSON, поле не входит в разрешённые поля ключа, нет X-NOVA-SESSION-ID у AI-операции с поисковым ключом, изображение больше 8 МБ или аудио больше 25 МБ | Нет, исправьте запрос |
401 | Нет заголовка X-NOVA-API-KEY, либо ключ неизвестен, просрочен или отозван. Также защищённый ключ (secured key) с неверной подписью или истёкшим сроком | Нет, исправьте ключ |
402 | Организация приостановлена (все операции отвечают 402, пока долг не погашен или API не возобновлён), либо кошелёк не покрывает AI-операцию | Только после пополнения или возобновления |
403 | Область ключа не покрывает операцию, функции операции нет в тарифе, коллекции нет в списке разрешённых для ключа, IP или Origin запроса не разрешён, ограничения ключа на уровне строк или полей нельзя применить к операции, поисковый ключ запросил разговор другой сессии | Нет |
404 | Путь, которого нет в контракте (Not Found), или несуществующий ресурс (Experiment … not found.) | Нет |
409 | Текущее состояние ресурса не допускает запрос. См. Конфликты | После смены состояния |
411 | Загрузка «сырого» тела без Content-Length (putMediaContent, uploadIngestFeed) | Нет |
413 | putMediaContent больше 100 МБ, uploadIngestFeed больше 500 МБ | Нет. См. лимиты |
429 | Месячная квота, лимит частоты или лимит AI-операций на сессию. См. лимиты | Да, после ожидания |
500 | Непредвиденная ошибка в операции контрольной плоскости (Internal server error), или кошелёк кредитов был недоступен | Да, с увеличением паузы |
502 | Поисковый движок недоступен (Search engine unavailable, retry later.) | Да, с увеличением паузы |
503 | Разомкнут предохранитель (circuit breaker) движка. Приходит с Retry-After: 10 | Да, после ожидания |
API не возвращает 422. Ошибки валидации приходят как 400.
Конфликты
409 всегда означает «не в этом состоянии». Какое состояние мешает, сказано в
сообщении:
| Операция | Конфликт |
|---|---|
startExperiment | Эксперимент уже запущен |
updateExperiment | Эксперимент запущен: остановите его перед изменением |
rollbackExperimentPromotion | Нет продвижения, которое можно откатить, или конфигурация с тех пор изменилась |
reindexCollection | Переиндексация коллекции уже в очереди или выполняется (в сообщении указана задача) |
putMediaContent | У ресурса уже есть содержимое |
createConnector | Этот Idempotency-Key уже использован с другим телом |
Повторные запросы
- Соблюдайте
Retry-After. Он есть в каждом429от квоты или лимита частоты, в секундах. Для месячной квоты это время до сброса, иногда дни. Покажите «квота исчерпана» вместо ожидания. Лимит AI-операций на сессию передаёт время ожидания вdata.retry_after, а не в заголовке. - На
500,502и503повторяйте с паузой. Паузу увеличивайте экспоненциально, со случайным разбросом, и остановитесь после нескольких попыток. - Не повторяйте
400,401,403,404,411и413: тот же запрос завершится так же. - Неудачные запросы не расходуют квоту. В месячную квоту идёт только успешный ответ поискового движка. Неудачный вызов модели не стоит кредитов, а его резерв освобождается.
Сгенерированные SDK выбрасывают типизированную ошибку для каждого
статуса. По умолчанию они повторяют 408, 429 и 5xx с увеличением паузы и
соблюдают Retry-After.
Идемпотентность
Повторная запись может выполниться дважды: первая попытка прошла, а ответ потерялся. Защиты две:
Idempotency-KeyвcreateConnector(POST /connectors). Передайте уникальное значение длиной до 255 символов. Повтор с тем же ключом и тем же телом вернёт исходный ответ, включая секрет коннектора, который показывается один раз. Тот же ключ с другим телом вернёт409. Остальные операции заголовок игнорируют.event_idв событиях.ingestEventsотбрасывает событие с уже сохранённымevent_idи учитывает его вdeduplicated. Пакет безопасно отправить повторно, если у каждого события естьevent_id(см. события).
У остальных операций записи ключа идемпотентности нет. Прежде чем повторять
создание, проверьте, не выполнилась ли первая попытка, например через
listExperiments.
У исходящей доставки событий своя политика повторов — шесть попыток с джиттером,
и повторяются только 408, 429 и 5xx. См.
Вебхуки.
Лимиты и квоты
Месячная квота запросов по тарифам и что в неё засчитывается, лимиты частоты по области ключа, лимит AI-операций на сессию и ограничения размера запросов.
Вебхуки
Получайте подписанные события AACSearch на своём эндпоинте — подписка, проверка HMAC-подписи, повторные попытки и диагностика неудачных доставок.