7even/vkontakte_api

Exception handling

proton opened this issue · 6 comments

Периодически при работе с Вконтакте возникают разные ошибки:
Проблемы с сетью (аля getaddrinfo: Name or service not known (SocketError))
Превышение лимита api (Too many requests per second)
И т.д.

Хотелось бы в данном случае избегать падения, а ждать пару секунд и повторять запрос (Ну и падать, если после пары попыток возникает ошибка).
Хотел спросить совета, как это лучше организовать, в голову хороших решений не лезет.

@proton Мы это решает с помощью банальных эксепшенов, т.е. если эксепшен возник, то пауза, потом перезапрос (при возможности смена токена, если у вас их несколько), раз 5 перезапросили, все фейл.

Ну это понятно, сложность в том, что нужно перезапустить конкретный запрос с конкретными параметрами.
К api обращаюсь из множества мест, думаю, как избежать дублирования кода.

P.S. Погуглил, узнал про retryable.

Вообще реализовать retry запроса в самом геме - мысль очень здравая. Добавлю в roadmap к следующей версии.

@7even я вижу появилась функция опция в настроках config.max_retries = 2

Есть вопросы =)

Какие типы ошибок ретраятся, а какие нет?
Просто видов ответа ВК огромное множество.

И тут важно что считается ошибкой и по какому принципу.
Просто могут быть ситуации, что ответ не ожиданный, но ошибкой он считаться не будет. Поэтому тут нужна точность. =)

Какая пауза между запросами? Похоже ее нет.
Эта фича была бы интересна для сетевых ошибок или вылезания за лимит запросов, но тогда нужна обязательно пауза.

Для этого используется стандартный фарадайный middleware :retry, а он перехватывает только StandardError и Timeout::Error, причем паузы перед повторным запросом нет.

Можно в принципе написать свой middleware, но для этого надо собрать список всех ошибок, которые будем ловить - потому что у меня сейчас нет в разработке приложений, использующих vkontakte_api.

Ошибки типа Too many requests per second, как и другие ошибки, выбрасываемые в виде VkontakteApi::Error, я бы не стал тут отлавливать - нет смысла долбить один и тот же ошибочный запрос, а если превышен лимит запросов - то нужна более тонкая логика определения интервала до следующего запроса.

OK, ладно, будем пользоваться. StandardError и Timeout::Error уже чать проблем закрывают.
Посмотрим, как это на практике работает.

Лично у нас сейчас стоит обработка по сл. видам ошибок

RETRY_EXCEPTIONS = [
VkontakteApi::Error,
Errno::ENETUNREACH,
Faraday::Error::TimeoutError,
Faraday::Error::ConnectionFailed
]

Есть еще и другие, но там, более хитрая логика, да.