Ruby

Ruby で例外を捕捉して一定回数 retry するメソッド

More than 1 year has passed since last update.

制御構文の retry を使うことで記述できます。

def retry_on_error(times: 3)
  try = 0
  begin
    try += 1
    yield
  rescue
    retry if try < times
    raise
  end
end

retry_on_error { do_something }

間違った例 or 無限リトライ

下のように記述すると、 try ローカル変数が毎回 0 を代入されるため、無限リトライになってしまいます。

def retry_on_error(times: 3)
  try = 0
  yield
rescue
  try += 1
  retry if try < times
  raise
end

無限リトライを記述するなら、下でよいです。

def retry_on_error
  yield
rescue
  retry
end

しかし、これは呼び出し元で記述した方がわかりやすいかもしれません。

retryable を使う

スリープを挟みたい、特定のエラーでのみリトライしたいなど、より複雑な制御をしたくなったときは、gem の retryable を使うとよいかもしれません。

Retryable.retryable do
  # do something
end

これだけで、 StandardError を捕捉して 1 秒の sleep を挟みつつ、2回までリトライしてくれます。

呼び出し時のオプションや Retryable.configure { |c| ... } で、細かなカスタマイズを行うことができます。

ピュア Ruby で書かれており、依存 gem もなく古いバージョンの Ruby でも動作するので、自前で複雑な制御を実装するよりは筋が良さそうです。

参考