Как читать ошибки JSON API: HTTP, status, path и request_id

Разделяем HTTP-ошибки, некорректную оболочку запроса, ошибку JSON внутри input и needs_review на примерах контракта Neraviko.

Посылка с отдельными отделениями как образ конверта ответа API и предупреждений

Запрос завершился, ответ содержит JSON, но нужного результата нет. Первое действие — сохранить HTTP-статус, тип ответа и безопасные диагностические поля. Один текст message редко объясняет, на каком слое возникла проблема: сеть, оболочка запроса, операция или проверка содержимого.

В API Neraviko операция отвечает в общей оболочке с request_id, operation, version, status, output, warnings, errors и meta. Значения status — success, needs_review и error. Этот контракт относится к Neraviko; у другого API имена и семантика могут отличаться.

Два JSON на разных уровнях

Синтетическое тело запроса к операции json.validate:

{"input":"{\"ready\":true,}","options":{}}

Внешнее тело корректно: поле input содержит строку. Внутри строки лежит некорректный JSON с финальной запятой. Проверка операции возвращает INVALID_JSON, путь /input и byte position 14.

Теперь другой запрос:

{"input":{"ready":true},"options":{}}

Здесь внешний JSON тоже корректен, но input — объект. Операция ожидает исходный текст, поэтому ошибка INVALID_INPUT_TYPE относится к типу входа. Исправление — сериализовать внутренний документ в строку, а не менять саму проверку.

Наконец, незакрытое внешнее тело вообще не доберётся до операционного JSON-парсера. Controller вернёт INVALID_REQUEST_JSON с HTTP 400. Если смешать эти три случая, можно бесконечно исправлять правильный уровень и оставлять настоящую причину.

Читать ответ в определённом порядке

Сначала проверьте, получен ли HTTP-ответ. Сетевой таймаут не даёт достоверного операционного envelope. Затем посмотрите HTTP-статус и Content-Type: HTML от промежуточного сервера не следует разбирать как JSON только из-за ожидания клиента.

После успешного разбора тела прочитайте status, затем errors или warnings. В Neraviko поле path указывает место в запросе, а position, когда присутствует, отсчитывает байты исходного текста с нуля. Для JSON Schema нарушения дополнительно содержат instance_path и schema_path.

Пути используют JSON Pointer. В его token символ ~ записывается как ~0, / как ~1; это нужно учитывать, если имя свойства само содержит slash. RFC 6901. Путь /input не означает, что весь input нужно стереть: он показывает область, внутри которой операция нашла проблему.

Коды для разных действий

Ответ Neraviko Что исследовать
415 UNSUPPORTED_MEDIA_TYPE Content-Type запроса
400 INVALID_REQUEST_JSON Внешнее JSON-тело
413 PAYLOAD_TOO_LARGE Полный размер сериализованного запроса
422 INVALID_INPUT_TYPE / INVALID_JSON Тип и содержимое input
429 RATE_LIMIT_EXCEEDED Лимит и Retry-After
200 needs_review Предупреждения и пригодность output

HTTP описывает семантику ответа, а операционный статус уточняет результат конкретной задачи. RFC 9110. Не повторяйте одинаковый запрос с неверным типом бесконечно: он не станет правильным от повторения.

Успешный HTTP и необходимость проверки

Следующий локальный JavaScript-пример показывает ветвление клиента. Объекты сокращены до полей, которые использует функция; это синтетические фрагменты, не реальные ответы сервера:

function classify(httpStatus, body) {
  if (httpStatus < 200 || httpStatus >= 300 || body.status === "error") {
    return "request failed";
  }
  if (body.status === "needs_review") return "review output";
  if (body.status === "success") return "completed";
  return "unexpected envelope";
}
console.log(classify(422, {status: "error"}));
console.log(classify(200, {status: "needs_review"}));
console.log(classify(200, {status: "success"}));

Вывод: request failed, review output, completed. Пример демонстрирует порядок обработки, но не заменяет проверку полной структуры ответа. Например, Schema mismatch с output.valid=false — завершённая проверка, которую нельзя назвать пригодным документом.

Диагностика без утечки input

Сохраните request_id и заголовок X-Request-ID, время, имя операции, HTTP-статус и code/path. Не записывайте токен Authorization и сырой пользовательский документ в общий журнал. Если нужен воспроизводимый случай, сделайте минимальный синтетический input с той же структурной проблемой.

При временном ограничении учитывайте Retry-After и политику повторов клиента. При отказе авторизации или scopes сверяйте права, а не обходите их. Для неизвестной серверной ошибки request_id помогает связать обращение с диагностикой владельца сервиса; он не раскрывает сырые данные и не является секретом доступа.

JSON validator Neraviko подходит для проверки минимального внутреннего документа. Форматтер помогает читать безопасную копию envelope. Обе операции серверные. Лимит нужно считать по фактическому сериализованному запросу: escape внутри строк увеличивает байты по сравнению с исходным видимым текстом.