12
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

retryable gem 触ってみた

Last updated at Posted at 2015-01-12

例外処理書く時あるよね

クローラを書いていると、「Webページから情報を取得する」動作を書くわけだが、ここは相手サーバの都合で様々なエラーを吐く。こんなときしばしば「n回トライしてだめだったら次いくよ」という例外処理を書く。

url_array.each do |url|
  counter = 0
  upto = 5

  begin
    html = open(url, &:read) # サーバ側の問題で、例外を吐く可能性がある部分
  rescue
    counter += 1
    retry if counter < upto
    next
  end

  # nokogiri = Nokogiri::HTML(html)
  # ...
end

retryable gemで簡潔な記述にすることができる。

Example

require "retryable"

# 例1) 最も単純な例

# ブロック引数はそれぞれ retries: 現在再試行回数(0〜n-1), 
# exception: 例外オブジェクト ( retries == 0 のとき exception == nil )

# 引数なしのとき、デフォルトのオプション
# (「全ての例外を捕まえる」「試行回数2回まで」「sleep 1秒」等)で動作
Retryable.retryable do |retries, exception|
  puts "run crazy code"
  1/0
end

# 例2) 「ZeroDivisionErrorだけを捕まえる」「試行回数5回まで」
Retryable.retryable(:on => [ ZeroDivisionError ], :tries => 5) do |retries, exception|
  # 例外による再試行状態にあるとき(retries > 0)、メッセージを出力
  puts "try #{retries} failed with exception: #{exception}" if retries > 0
  1/0
end

冒頭のコードと同じことをやりたければ、こう書けば良い。
ブロックの最後の値が返り値になる。

# 例3) 5回試行しても失敗するような場合は次のループ処理に移る
url_array.each do |url|
  html = Retryable.retryable(:tries => 6) do |r, e|
    next if r == 5
    open(url, &:read)
  end

  # nokogiri = Nokogiri::HTML(html)
  # ...
end

参考

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?