Перезапуск блока кода, который стал причиной исключения

в 9:31, , рубрики: exception, retry, ruby

Не так давно я обнаружил одну интересную фичу в Руби. Мне показалась, что она может быть весьма полезной в определенных ситуациях. Тем не менее, я пришел к выводу, что этот трюк не так уж частно используется в коде, так как за многие годы программирования наткнулся я на него только сейчас. Идея в том, что мы можем дать еще один шанс коду, который привел к исключению (exception) и запустить его повторно. Давайте посмотрим, насколько легко это делается в руби.
Мы оборачиваем определенный код в блок begin и, когда нам нужно будет запустить этот блок еще раз, просто пишем ключевое слово retry. Это может быть использовано в случае с подключением к внешним сервисам или API, которые могут работать нестабильно и иногда выдавать timeout или другие ошибки.
Итак, давайте рассмотрим один простенький пример применения этому. Мы напишем метод, который будет имитировать соединение и с вероятностью примерно в 30 процентов будет выдавать исключение. Чтобы это сделать, внутри мы будем генерировать случайное число и если этим числом окажется единица — выдавать исключение.

def connect
  tries = 0
  max_tries = 3
  begin
    raise if rand(3) == 1
  rescue
    tries += 1
    if tries == max_tries
      raise "We have tried #{tries} times but it still fails"
    else
      retry
    end
  end
end

Здесь у нас есть переменная tries, в которой мы подсчитываем сколько раз мы уже попытались запустить указанный блок. Это необходимо для того чтобы не допустить бесконечный цикл. Переменная max_tries указывает максимальное число попыток, после которого мы должны перестать пытаться запустить код и все таки выдать ошибку. Как видите, вся магия происходит в rescue блоке, когда мы вызываем retry.

Автор: heel

Источник

Поделиться

* - обязательные к заполнению поля