Техническое руководство
Карта ошибок API gateway для разных моделей
Карта ошибок API gateway нужна не для того, чтобы объявить разные модели одинаковыми, а чтобы ваше приложение одинаково безопасно реагировало на наблюдаемые сбои. Backend сопоставляет HTTP-статус и проверенную форму ответа с локальной категорией, сохраняет безопасный request ID и показывает пользователю понятный следующий шаг. RussiaAPI — независимый gateway; конкретные коды, поля и маршруты подтверждаются только текущей документацией и тестом.
Отделите наблюдаемый факт от предположения о причине
Начните с минимального набора фактов: локальный correlation ID, HTTP status, длительность, выбранный alias, версия адаптера и нормализованная категория. Например, 400 или 422 обычно означает, что запрос требует исправления, 401 или 403 — что нужно проверить локальную авторизацию или доступ, 429 — что приложению следует применить свою очередь либо backoff, а 5xx и сетевой timeout — что результат неизвестен. Это не диагноз конкретного поставщика и не повод подменять ошибку успехом.
Не сохраняйте Authorization, API key, полный prompt, cookie, необработанное тело ошибки или URL с временными параметрами. Такие данные редко нужны для первой линии поддержки и могут содержать персональные либо коммерческие сведения. Если требуется расширенная диагностика, включайте её отдельно, с коротким сроком хранения и фильтрацией. Пользователь должен видеть понятное сообщение: что можно изменить, можно ли повторить операцию и где найти безопасный ID обращения.
Сделайте локальную карту короткой и тестируемой
Удобная карта хранится в коде приложения и не зависит от названия модели: invalid_input, access_check, rate_limited, upstream_unavailable, contract_invalid и unknown_failure. Каждая категория имеет user-safe текст, действие для интерфейса, правило повтора и уровень журналирования. Не создавайте фиктивный «единый код», если исходный контракт не подтверждён. Оригинальный status можно хранить рядом с локальной категорией для инженера, но не показывать пользователю внутренний текст upstream-ошибки без очистки.
Для каждой записи добавьте тест с синтетическим ответом. Проверьте пустое тело при 502, невалидный JSON при 200, 429 без Retry-After, 403 без подробности и timeout, когда неизвестно, была ли операция принята. Сценарий с записью, публикацией, оплатой или видео-задачей не должен автоматически повторяться: сначала проверьте локальный idempotency key и статус вашей записи. Продуктовый маршрут может предлагать ручную повторную попытку только там, где это безопасно.
Свяжите UI, очередь и поддержку
Интерфейс не должен показывать «модель сломалась», если у вас есть только timeout. Показывайте состояние, которое реально известно: «ответ ещё не подтверждён», «попробуйте позже», «исправьте поле» или «обратитесь в поддержку с ID». Для rate limit поставьте запрос в собственную очередь либо предложите пользователю повтор после контролируемой паузы; бесконечный автоповтор увеличит нагрузку и замаскирует проблему. Для access_check не просите пользователя прислать ключ или скриншот секретов.
Наблюдаемость полезна, когда у команды есть порог и владелец решения. Отслеживайте долю нормализованных категорий, p95 длительности, длину очереди и число отмен без пользовательского текста. При резком отклонении остановите rollout feature flag-ом, сравните версию адаптера с последней проверенной и повторите короткий контрактный тест. Не обещайте постоянную доступность, фиксированный лимит или одинаковую семантику ошибок между моделями.
Контрольный список перед релизом
До изменения production сохраните версию адаптера, владельца решения, дату проверки и безопасный способ отключения. Прогоните положительный сценарий на синтетическом входе и отдельные отрицательные случаи: пустое поле, неверный tenant, недоступный alias, timeout и повтор того же запроса. Измеряйте только технические признаки, достаточные для поддержки, а не содержимое пользователя.
После релиза наблюдайте за нормализованными кодами ошибок, длительностью, очередью и долей отменённых операций. Если один из сигналов выходит за заранее согласованный порог, остановите rollout, не расширяйте доступ автоматически и проверьте текущий договорный каталог. Такая дисциплина полезна независимо от выбранной модели и не подменяет требования к данным, авторским правам, согласию или внутреннему контролю.
Server-side пример
Этот минимальный пример рассчитан на Node.js 18+ и защищённый server-side запуск. Он не содержит реального ключа и не утверждает наличие недокументированной функции; перед интеграцией подтвердите текущий маршрут, alias модели и схему payload.
export function normalizeGatewayError({ status = 0, requestId, retryAfter }) {
const safeRequestId = typeof requestId === 'string' ? requestId.slice(0, 128) : undefined;
if (status === 400 || status === 422) return { kind: 'invalid_input', retry: false, requestId: safeRequestId };
if (status === 401 || status === 403) return { kind: 'access_check', retry: false, requestId: safeRequestId };
if (status === 429) return { kind: 'rate_limited', retry: true, retryAfterMs: Number.isFinite(retryAfter) ? Math.max(0, retryAfter) : undefined, requestId: safeRequestId };
if (status >= 500 || status === 0) return { kind: 'upstream_unavailable', retry: true, requestId: safeRequestId };
return { kind: 'unknown_failure', retry: false, requestId: safeRequestId };
}
// Keep raw upstream bodies out of ordinary logs; test this map with synthetic responses.Проверьте синтаксис командой node --check, добавьте собственную аутентификацию, контролируемые лимиты и тесты отрицательных сценариев. Не добавляйте в журнал тело запроса, ответ целиком или авторизационные заголовки.
Проверьте сценарий в RussiaAPI
Создайте собственный тестовый ключ в консоли, сверьте текущий каталог моделей и выполните обезличенный server-side smoke test. Расширяйте нагрузку только после измеримой проверки.
FAQ
Можно ли считать 429 гарантированным временем повтора?
Нет. Заголовок и политика могут отсутствовать или меняться. Используйте локальную очередь, ограниченную паузу и собственные метрики, а значения статуса и заголовков трактуйте как проверяемый сигнал текущего контракта.
Нужно ли показывать пользователю сырой текст API ошибки?
Обычно нет. Он может раскрыть технические детали или данные. Покажите безопасное действие и ID обращения, а очищенный технический контекст оставьте для ограниченной server-side диагностики.
Почему timeout нельзя автоматически повторять всегда?
Timeout не сообщает, дошла ли операция до обработки. Повтор операции с side effect может создать дубль. Используйте локальный idempotency key, проверьте состояние своей задачи и только затем предложите безопасный путь продолжения.