Перейти к основному содержимому

Ошибки API

Ошибки возвращаются в формате application/problem+json по RFC 7807. Формат один для всех эндпоинтов, поэтому обработчик ошибок можно написать один раз. Отдельно стоит различать две вещи: отказ на сам запрос и неудачу асинхронной операции, которая была принята и упала позже.

Тело ошибки

Стандартные поля RFC 7807 присутствуют во всех ответах об ошибке: type, title, status, detail и instance. Поля title и detail написаны для человека и могут быть переформулированы без предупреждения — не разбирайте их в коде и не сравнивайте строки.

Кроме стандартных полей API добавляет code — устойчивый машиночитаемый признак конкретной ошибки. Именно по нему следует различать ситуации. Если признака нет, поле в теле отсутствует.

Поле code объявлено не у всех ответов

В текущей версии схемы тип с полем code заявлен ровно у одного ответа — 409 при создании машины, где code равен insufficientCapacity. Остальные ответы об ошибке описаны базовым типом без code. Пишите обработчик так, чтобы отсутствие поля не ломало логику: читайте code, если он есть, и опирайтесь на HTTP-код, когда его нет.

Коды ответов

  • 400 — запрос не прошёл валидацию. Тело содержит карту errors: имя поля и список сообщений по нему. Сюда же попадают неверные значения sorts и filters — например, ссылка на поле, которое эндпоинт не поддерживает.

  • 401 — запрос не аутентифицирован: нет действующей сессии Keycloak или токена Bearer.

  • 404 — ресурс не найден. Проверьте, что идентификаторы в пути принадлежат одному проекту: машина из чужого проекта выглядит как отсутствующая.

  • 409 — конфликт состояния. Самый частый случай: над ресурсом уже выполняется другая операция.

  • 503 — эндпоинт временно отключён. Сейчас так отвечает изменение конфигурации машины при любом вводе.

Конфликты 409 и что с ними делать

Код 409 покрывает несколько разных ситуаций, и реакция на них тоже разная.

  • Занят другой операцией. Пока над машиной, сетью или адресом идёт операция, остальные изменения того же ресурса отклоняются. Дождитесь, пока status ресурса выйдет из creating, updating или deleting, и повторите запрос.

  • Не хватает мощностей. При создании машины возвращается code со значением insufficientCapacity. Списания не происходит, машина не создаётся. Повторите позже или выберите конфигурацию меньше — заранее это видно по полям availability и maxCount в списке конфигураций.

  • Ресурс ещё занят. Проект нельзя удалить, пока в нём есть машины, сети или публичные адреса; SSH-ключ нельзя удалить, пока он авторизован хотя бы на одной машине; публичный адрес нельзя освободить, пока он используется. Сначала уберите зависимости.

Ошибка запроса и сбой операции — разные вещи

Ответ 202 означает, что работа принята. Если она упадёт позже, HTTP-ошибки уже не будет: об исходе расскажет запись операции. Её поле status принимает значение Failed, а failureCode отвечает, почему.

  • insufficientCapacity — в кластере не нашлось узла под запрошенную конфигурацию.

  • timeout — операция не завершилась за отведённое время.

  • internal — любая другая или неклассифицированная причина.

Помните, что штатно обработанный сбой операции оставляет ресурс в состоянии active. Значит, судить об исходе по status ресурса нельзя — читайте операцию. Подробнее об этом на странице «Статусы и жизненный цикл».

Что логировать

Пишите в лог status, code и instance из тела ошибки, а для асинхронных сбоев — идентификатор операции и failureCode. Поле currentState у операции удобно для чтения человеком, но набор его значений не стабилен, поэтому строить на нём условия не нужно.

Связанные эндпоинты