Практическое руководство: обработка ошибок
Практическое руководство: обработка ошибок
Введение
В этом руководстве рассматривается обработка ошибок при взаимодействии с API-интерфейсом C2C. Корректная обработка ошибок HTTP — важнейшая часть надежной интеграции с любой сторонней службой.
Типы ошибок
Ошибки в вашей интеграции могут появляться из различных источников, которые можно разделить на четыре основные группы:
- Ошибки ввода-вывода: возникают в результате аппаратных операций на вашем устройстве, например при сбоях операций чтения/записи.
- Ошибки приложения: возникают из-за проблем в коде вашего приложения.
- Сетевые ошибки: возникают в сетевом стеке и передаются вашей сетевой библиотекой.
- Ошибки API-интерфейса: генерируются серверными службами Frame.io.
Для каждой категории ошибок нужен свой подход к обработке. Это руководство посвящено в основном ошибкам API-интерфейса, но мы рассмотрим и общие стратегии для других категорий.
Как API-интерфейс возвращает ошибки
API-интерфейс Frame.io передает ошибки с помощью двух основных механизмов:
- Коды состояния: коды ошибок HTTP, которые указывают на характер проблемы.
- Сообщения об ошибках: содержимое нагрузки, которое предоставляет дополнительные сведения об ошибке, особенно когда несколько разных ошибок имеют одинаковый код состояния.
Коды состояния ошибок
Коды состояния HTTP — это стандартизированные числовые ответы, которые сообщают результат HTTP-запроса. Подробнее см. документацию по кодам состояния HTTP от Mozilla или HTTP Cats с очень наглядными иллюстрациями. Каждая конечная точка API-интерфейса Frame.io указывает ожидаемый код состояния успеха — обычно 200 (OK), 201 (Created) или 204 (No Content). Вы можете убедиться, что запрос успешно выполнен, либо проверив эти конкретные коды, либо убедившись, что код находится в диапазоне 200–299. Коды состояния выше 399 указывают на ошибки. Большинство ошибок API-интерфейса возвращают коды 4XX (400-499), указывая на проблемы на стороне клиента. Ошибки за пределами этого диапазона обычно возникают в сетевой инфраструктуре между вашим устройством и нашей службой, за исключением ошибки 500 (Internal Server Error), которая указывает на неожиданную проблему на нашем сервере. Кроме того, ответ 404 (Not Found) может быть передан промежуточными сервисами, а не нашим сервером, несмотря на то что это код 4XX.
Если вы получили неожиданный код состояния, сообщите об этом нашей команде.
Схемы данных об ошибках
Frame.io возвращает сведения об ошибках в двух форматах: простом и подробном. Ваша логика обработки ошибок должна учитывать оба формата.
Простая схема информации об ошибках
Вот пример запроса с неправильным client_secret, что привело к ошибке:
Ответ:
Простая схема содержит только одно поле для идентификации ошибки.
Подробная схема информации об ошибках
Для сравнения, вот запрос без надлежащей авторизации:
Ответ:
Подробные ошибки содержат поле message, которое описывает тип ошибки.
Определение типа ошибки
При обработке ошибок Frame.io сначала проверьте наличие структурированных данных об ошибке, а затем используйте код состояния HTTP, если такие данные отсутствуют.
Пример базовой реализации обработки ошибок:
Справочные таблицы ошибок, упомянутые в этом примере, предоставлены в конце данного руководства.
Ошибки AWS
При добавлении фрагментов файлов вы работаете напрямую с AWS S3, который имеет собственный формат ошибок. Подробную информацию см. в документации по распространенным ошибкам AWS. Как правило, при несущественных ошибках AWS следует сделать еще как минимум одну попытку.
Ошибки AWS возвращаются в формате XML:
Элемент Code идентифицирует тип ошибки.
Повторные попытки при ошибках
Когда повторять запросы
В таблицах ошибок в этом руководстве указано, при каких ошибках API-интерфейса нужно сделать еще одну попытку. Что касается ошибок, вызванных не API-интерфейсом, а операциями ввода-вывода, сетевыми библиотеками или AWS, рекомендуем повторять те, которые могут возникнуть из-за временных условий. Перегрузка сети, временные отключения сервера или потеря пакетов обычно требуют повторных попыток. Большинство сетевых библиотек вызывают ошибку TimeoutError, когда выполнение запроса занимает слишком много времени. Это основной случай, когда нужно повторить попытку.
Если есть сомнения, попробуйте еще раз
В вычислительных средах могут возникать непредсказуемые проблемы. Даже если ошибка кажется фатальной, часто стоит сделать одну повторную попытку. Временные состояния системы, аппаратные сбои (например переворот битов космическими лучами) или иногда состояния памяти могут вызывать ошибки, которые кажутся фатальными, но разрешаются при второй попытке. Однако для некоторых ошибок выполнять повторные попытки не следует. Например, ответ 409: CHANNEL PAUSED при создании ресурса указывает, что устройство приостановлено и не должно выполнять добавление. Это состояние установлено преднамеренно и вряд ли изменится при повторной попытке.
Экспоненциальная задержка
Frame.io реализует ограничение скорости, при превышении ограничений возникает либо ошибка 429: Slow Down, либо состояние 400 со следующими структурированными данными:
Получив такие ответы, включите экспоненциальную задержку для повторных попыток. Рекомендуемая формула для расчета задержки (в секундах):
Где attempt начинается с 0. В результате задержка постепенно увеличивается: 0,5 с, 1 с, 2 с, 4 с, 8 с, 16 с, 32 с, и для всех последующих попыток составляет 32 секунды.
Произвольное изменение времени задержки
Мы рекомендуем добавить к времени задержки случайный компонент, чтобы предотвратить синхронизацию повторных запросов от нескольких устройства после одного и того же состояния ошибки. Это помогает снизить риск стадного эффекта, когда многие устройства одновременно повторяют запросы после сбоя. Лучший вариант — добавить случайное смещение между 0 и половиной рассчитанной задержки: math.rand(0, delay // 2).
Экспоненциальная задержка необходима для ошибок, вызванных ограничением скорости, а также полезна для обработки сетевых и ошибок ввода-вывода в целом. Такой подход позволяет дождаться, пока временные ограничения ресурсов разрешатся, не создавая дополнительную нагрузку повторными запросами.
Обнаружение состояния отключения
Сетевые ошибки могут указывать на то, что Frame.io недоступен по следующим причинам:
- Локальная сеть не работает
- Службы Frame.io испытывают проблемы
- Промежуточный сетевой компонент не работает
Важно различать эти ситуации. Если ошибка указывает на проблему с подключением, запустите задачу мониторинга, которая проверит восстановление службы и проинформирует пользователя об отключении.
Ожидание подключения и авторизации
Спроектируйте приложение так, чтобы оно не делало ненужных запросов, когда устройство обновляет авторизацию, ожидает авторизации пользователя или не может связаться с Frame.io. Это снизит нагрузку на сеть и сделает работу пользователя более удобной.
Блокируйте все вызовы API-интерфейса (кроме https://api.frame.io/health), когда обнаруживаете состояние отключения. При возникновении проблем с подключением запустите фоновую задачу, которая опрашивает конечную точку состояния и блокирует дальнейшие вызовы API-интерфейса до восстановления подключения.
Аналогично, если истек срок действия токена, блокируйте вызовы, зависящие от авторизации, до выдачи нового токена. Если обновить токен не удается, предупредите пользователя, что необходима повторная аутентификация.
При опросе состояния подключения применяйте тот же подход с экспоненциальной задержкой, описанный ранее.
Таймауты запросов
Настройте соответствующие значения таймаута для разных типов запросов:
- По умолчанию: 15 секунд для базовых запросов
- Обновление авторизации: 2 минуты с учетом потенциальной обработки на сервере
- Добавление фрагмента файла: 5 минут для работы с медленными сетями при передаче больших данных
Пример обработчика повторов
Реализация в псевдокоде, показывающая обработку ошибок с экспоненциальной задержкой:
Таблицы ошибок
В следующих таблицах приведены категории ошибок API-интерфейса Frame.io и рекомендации по их обработке. Вот что означает каждый столбец:
Сообщение: идентификатор сообщения структурированных данных об ошибке Код HTTP: код состояния HTTP Тип ошибки: логическая категория ошибки (подробно описана в разделе Описания) Схема: формат структурированных данных об ошибке (простой или подробный) Повтор: рекомендация по повторным попыткам (да — несколько попыток, одна — одна попытка, нет — критическая ошибка) Звездочки (*) означают, что в разделе Описания приведены особые указания.
Сообщения об ошибках Frame.io
Коды состояния Frame.io
Ошибки AWS
Подробное описание см. в документации AWS.
Разбор похожих ошибок AWS
Как SlowDown, так и ServiceUnavailable, возвращенные AWS, указывают на проблемы с частотой запросов и могут обрабатываться аналогично ошибке SlowDown, возвращенной Frame.io, с использованием экспоненциальной задержки. Аналогичным образом ошибка InternalError, возвращенная AWS, по смыслу соответствует ошибке InternalServerError в нашем API-интерфейсе.
Описания
AccessDenied
Возвращается, когда пользователь отклоняет авторизацию во время сопряжения устройства.
AuthorizationPending
Указывает, что пользователь еще не ввел код сопряжения устройства. Продолжайте опрос после периода interval, указанного в ответе с кодом устройства.
ChannelPaused
Канал устройства был приостановлен при создании ресурса. Не пытайтесь добавить этот ресурс снова.
ExpiredToken
Срок действия кода сопряжения устройства истек. Создайте новый код и перезапустите процесс сопряжения.
InternalServerError
Указывает на неожиданную проблему сервера. Повторите попытку один раз. Сообщайте нашей команде об ошибках 500, чтобы мы провели расследование. Обратите внимание: что некоторые известные проблемы возвращают ошибку 500, хотя должны возвращать InvalidRequest:
- Попытка добавления в несуществующий канал устройства
- Запрос недопустимого количества пользовательских фрагментов
InvalidArgument
Параметр полезной нагрузки содержал недопустимое значение. Убедитесь, что значения параметров соответствуют ожиданиям API-интерфейса.
InvalidContentType
Заголовок Content-Type запроса не поддерживается. API-интерфейс обычно принимает:
form/multipart(только конечные точки авторизации)application/x-www-form-urlencoded(все конечные точки)application/json(конечные точки без авторизации)
InvalidClient
Предоставленные учетные данные (client_id, client_secret и т. д.) не распознаны. Проверьте учетные данные интеграции.
InvalidClientVersion
Заголовок x-client-version был продублирован или содержит недопустимую семантическую версию.
InvalidGrant
Тип разрешения авторизации недействителен. Правильные значения приведены в руководствах по авторизации.
InvalidRequest
Параметры запроса или формат полезной нагрузки неверны. Проверьте имена полей и форматы значений.
Если ошибка возвращена во время обновления токена, ваш срок действия токена обновления истек, и нужно перезапустить процесс авторизации.
SlowDown
Вы превысили ограничение частоты запросов. Используйте экспоненциальную задержку для последующих запросов. Обратите внимание, что эту ошибку может вызвать выполнение нескольких запросов кода устройства через одно и то же подключение TCP — создавайте новые подключения для каждого запроса сопряжения.
UnauthorizedClient
Обычно указывает на истекший или отсутствующий access_token. Если возвращена эта ошибка, обновите токен перед повторной попыткой.
Если ошибка возникает при обновлении токена, необходимо перезапустить процесс авторизации и предложить пользователю повторно подключиться.
Эта ошибка также может возникнуть при доступе к ресурсам вне области авторизации вашего устройства или когда проект отключил устройства C2C. Убедитесь, что вы запросили соответствующие области во время авторизации.
Если эта ошибка возникает при обновлении токена, весь процесс авторизации должен быть перезапущен с участием пользователя.
Дальнейшие шаги
Мы рекомендуем обращаться к нашей команде с любыми вопросами и переходить к руководству по расширенному добавлению. Мы с удовольствием поможем вам в продолжении изучения процессов интеграций. Если вы еще не сделали этого, просмотрите руководство Реализация C2C: настройка перед продолжением. Вам понадобится access_token, полученный в процессе аутентификации и авторизации. Это руководство основано на руководстве по базовому добавлению и руководстве по расширенному добавлению.