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

Коды ошибок Ozon Seller API и обработка ошибок

Обзор

Ozon Seller API использует комбинированную систему кодов ошибок, включающую:

  • HTTP статусы - основные коды состояния HTTP
  • Числовые коды ошибок Ozon - специфические коды ошибок платформы
  • Строковые коды ошибок - описательные коды для конкретных сценариев

HTTP Статус коды

400 Bad Request - Ошибка клиента

Python исключение: OzonAPIClientError

Описание: Неверный формат запроса, невалидные данные или параметры.

Частые причины:

  • Неверный JSON формат в теле запроса
  • Отсутствие обязательных полей
  • Неверные значения параметров
  • Нарушение валидации данных

Пример ответа:

{
"code": 400,
"message": "Bad Request",
"details": [
{
"field": "price",
"message": "Ставка не входит в диапазон допустимых значений"
}
]
}

403 Forbidden - Ошибка доступа

Python исключение: OzonAPIForbiddenError

Описание: Доступ запрещён или недостаточно прав.

Частые причины:

  • Offer not signed - в личном кабинете продавца отсутствует подписанная офферта
  • Обращение к методу, недоступному в текущей роли
  • Недостаточно прав для выполнения операции

Пример ответа:

{
"code": 403,
"message": "Forbidden",
"details": "Offer not signed"
}

404 Not Found - Ресурс не найден

Python исключение: OzonAPINotFoundError

Описание: Запрашиваемый ресурс не существует или недоступен.

Частые причины:

  • Invalid Api-Key - неверный API ключ
  • Несуществующий endpoint URL
  • Удалённый ресурс (товар, заказ и т.д.)

Пример ответа:

{
"code": 404,
"message": "Not Found",
"details": "Invalid Api-Key, please contact support"
}

409 Conflict - Конфликт

Python исключение: OzonAPIConflictError

Описание: Конфликт состояния ресурса с выполняемой операцией.

Частые причины:

  • Попытка создать уже существующий ресурс
  • Конфликт версий при обновлении
  • Нарушение бизнес-логики

Пример ответа:

{
"code": 409,
"message": "Conflict",
"details": "Product already exists"
}

429 Too Many Requests - Превышение лимита запросов

Числовой код ошибки Ozon: 8

Описание: Превышен лимит частоты запросов.

Глобальные лимиты (на 19 мая 2025):

  • 50 запросов в секунду на Client ID

Пер-Endpoint лимиты:

  • /v2/posting/fbo/product-list: 5 запросов в секунду
  • /v3/posting/fbo/list: 5 запросов в секунду
  • Информационные запросы штрихкодов: 2 запроса в секунду
  • Аналитика: различные лимиты по типу отчёта

Пример ответа:

{
"code": 8,
"message": "Too many requests",
"details": "Rate limit exceeded. Please retry later."
}

500 Internal Server Error - Ошибка сервера

Python исключение: OzonAPIServerError

Описание: Внутренняя ошибка сервера Ozon.

Частые причины:

  • Временные сбои на стороне Ozon
  • Ошибка в обработке запроса
  • Проблемы с инфраструктурой

Рекомендация: Повторить запрос через некоторое время.

Пример ответа:

{
"code": 500,
"message": "Internal Server Error",
"details": "An unexpected error occurred. Please try again later."
}

Специфические коды ошибок Ozon

"Circle is open" - Блокировка метода

Описание: Система блокирует работу метода на несколько минут при выполнении слишком большого количества запросов.

Тип ошибки: Rate limiting / Request throttling

Причина: Превышение порога частоты запросов

Длительность блокировки: Несколько минут

Решение:

  1. Реализовать rate limiting на стороне клиента
  2. Использовать экспоненциальную задержку (exponential backoff)
  3. Оптимизировать код для уменьшения количества запросов
  4. Мониторить частоту запросов

Строковые коды ошибок

Ошибки API ключей (обновлено февраль 2025)

  • INVALID_API_KEY - Неверный API ключ
  • API_KEY_DISABLED - API ключ отключён
  • API_KEY_EXPIRED - Срок действия API ключа истёк

Ошибки товаров и цен

  • PRICE_IS_NOT_SENT - товар ещё не создан или находится на стадии обновления
  • MP_DELIVERY_ONLY_3PL_ERROR - товар нельзя размещать на складе с методом доставки «Ozon»
  • PRODUCT_NOT_FOUND - товар не найден
  • INVALID_PRODUCT_ID - неверный ID товара

Ошибки атрибутов товаров

  • MISSING_REQUIRED_ATTRIBUTE - отсутствует обязательный атрибут
  • INVALID_ATTRIBUTE_VALUE - неверное значение атрибута
  • TYPE_ID_REQUIRED - не указан тег type_id

Ошибки категорий

  • INVALID_CATEGORY_ID - неверная категория
  • CATEGORY_NOT_FOUND - категория не найдена

Структура ошибок в ответах API

Базовая структура ошибки

{
"code": <числовой_код>,
"message": "<текст_ошибки>",
"details": [<дополнительная_информация>]
}

Пример полной структуры ошибки

{
"code": 5,
"message": "Validation error",
"details": [
{
"code": "MISSING_REQUIRED_FIELD",
"field": "barcode",
"message": "Поле 'barcode' обязательно для заполнения"
},
{
"code": "INVALID_VALUE",
"field": "price",
"message": "Цена должна быть больше 0"
}
]
}

Структура ошибок в операциях с товарами

{
"product_id": 12345,
"offer_id": "PRODUCT-001",
"errors": [
"Ошибка 1: описание ошибки",
"Ошибка 2: описание ошибки"
]
}

Обработка ошибок

Python (с библиотекой ozon-api)

from ozon_api import OzonAPIError, OzonAPIClientError, OzonAPIForbiddenError
from ozon_api import OzonAPINotFoundError, OzonAPIConflictError, OzonAPIServerError

try:
response = await api.product_list(request)
except OzonAPIClientError as e:
print(f"Ошибка клиента (400): {e.message}")
except OzonAPIForbiddenError as e:
print(f"Ошибка доступа (403): {e.message}")
print("Проверьте подписанную офферт в личном кабинете")
except OzonAPINotFoundError as e:
print(f"Ресурс не найден (404): {e.message}")
print("Проверьте API ключ")
except OzonAPIConflictError as e:
print(f"Конфликт (409): {e.message}")
except OzonAPIServerError as e:
print(f"Ошибка сервера (500): {e.message}")
print("Повторите запрос позже")
except OzonAPIError as e:
print(f"Общая ошибка API: {e.message}")

Обработка rate limiting (429)

import asyncio
from asyncio import sleep

async def call_with_retry(api_call, max_retries=5):
for attempt in range(max_retries):
try:
return await api_call()
except Exception as e:
if e.code == 8 or e.status == 429: # Rate limit
wait_time = 2 ** attempt # Экспоненциальная задержка
print(f"Rate limit exceeded. Waiting {wait_time}s...")
await sleep(wait_time)
else:
raise e
raise Exception("Max retries exceeded")

Go (с библиотекой ozon-api-client)

package main

import (
"fmt"
"github.com/diphantxm/ozon-api-client/ozon"
)

func handleError(err error) {
if ozonErr, ok := err.(*ozon.Error); ok {
switch ozonErr.StatusCode {
case 400:
fmt.Printf("Client Error: %s\n", ozonErr.Message)
case 403:
fmt.Printf("Forbidden: %s\n", ozonErr.Message)
case 404:
fmt.Printf("Not Found: %s\n", ozonErr.Message)
case 429:
fmt.Printf("Rate Limit: %s\n", ozonErr.Message)
case 500:
fmt.Printf("Server Error: %s\n", ozonErr.Message)
default:
fmt.Printf("Unknown Error: %s\n", ozonErr.Message)
}
}
}

Стратегии обработки ошибок

1. Retry Logic (Повторные попытки)

Применимо для:

  • HTTP 429 (Too Many Requests)
  • HTTP 500 (Internal Server Error)
  • Временных сетевых ошибок

Стратегия:

  • Экспоненциальная задержка (exponential backoff)
  • Максимум 3-5 попыток
  • Увеличение времени ожидания между попытками

2. Логирование ошибок

Рекомендации:

  • Логировать все ошибки с контекстом
  • Сохранять request ID для трассировки
  • Записывать параметры запроса (без чувствительных данных)
  • Фиксировать timestamp для анализа

3. Мониторинг

Метрики для отслеживания:

  • Частота ошибок по типам
  • Время ответа
  • Процент неудачных запросов
  • Количество retry операций

4. Обработка специфических ошибок

Invalid Api-Key (404):

  • Проверить корректность API ключа
  • Убедиться, что ключ не отозван
  • Проверить права доступа роли

Offer not signed (403):

  • Подписать офферту в личном кабинете
  • Проверить роль пользователя

"Circle is open":

  • Уменьшить частоту запросов
  • Реализовать пакетную обработку
  • Добавить задержки между запросами

Лучшие практики

1. Rate Limiting на стороне клиента

import asyncio
from asyncio import Semaphore

sem = Semaphore(10) # Максимум 10 одновременных запросов

async def limited_request(api_call):
async with sem:
return await api_call()

2. Пакетная обработка запросов

# Вместо множества одиночных запросов
for product_id in product_ids:
await api.get_product(product_id)

# Используйте пакетные запросы
await api.get_products(product_ids)

3. Асинхронная обработка

# Используйте асинхронные библиотеки
# для эффективной обработки множественных запросов
tasks = [api.get_product(id) for id in product_ids]
results = await asyncio.gather(*tasks)

4. Circuit Breaker Pattern

from circuitbreaker import circuit

@circuit(failure_threshold=5, recovery_timeout=60)
async def api_call_with_circuit_breaker():
return await api.some_method()

Диагностика и устранение неполадок

Типичные сценарии ошибок

Сценарий 1: Множественные ошибки 400

Симптомы: Частые ошибки Bad Request

Причины:

  • Неверная структура данных
  • Отсутствие обязательных полей
  • Неверные типы данных

Решение:

  1. Проверить схему JSON для endpoint
  2. Валидировать данные перед отправкой
  3. Использовать TypeScript или Pydantic для проверки типов

Сценарий 2: Ошибки 403 Forbidden

Симптомы: Доступ запрещён к определённым методам

Причины:

  • Недостаточно прав роли
  • Не подписана оферта
  • Метод недоступен для текущего типа аккаунта

Решение:

  1. Проверить права в личном кабинете
  2. Подписать офферту
  3. Связаться с поддержкой

Сценарий 3: Частые ошибки 429

Симптомы: Превышение лимитов запросов

Причины:

  • Слишком высокая частота запросов
  • Отсутствие rate limiting на клиенте
  • Неоптимизированные алгоритмы

Решение:

  1. Реализовать rate limiting
  2. Использовать пакетные запросы
  3. Кэшировать результаты
  4. Оптимизировать логику приложения

Полезные ресурсы

Официальная документация

Клиентские библиотеки

Сообщество

Дополнительные материалы


Резюме

Основные HTTP статусы

  • 400 - Ошибка клиента (невалидные данные)
  • 403 - Доступ запрещён (нет прав или не подписана оферта)
  • 404 - Ресурс не найден (неверный API ключ)
  • 409 - Конфликт (дубликаты, version conflicts)
  • 429 - Превышение лимитов (код ошибки 8)
  • 500 - Ошибка сервера

Специфические коды

  • "Circle is open" - Блокировка за превышение частоты запросов
  • Invalid Api-Key - Неверный API ключ (404)
  • Offer not signed - Не подписана оферта (403)

Лучшие практики

  1. Реализовать rate limiting на клиенте
  2. Использовать exponential backoff для 429 и 500 ошибок
  3. Логировать все ошибки с контекстом
  4. Использовать асинхронные запросы
  5. Применять пакетную обработку данных
  6. Мониторить метрики ошибок

Дата создания: 2025-02-10 Версия API: Актуально на 2025 год