« AHBL停止でメールエラー Main RubyのWindowsバイナリ選び »

Ruby Mechanize: Basic認証でのエラー時の対応

あるBasic認証が必要なサイトでアクセスのタイミングの問題なのか、通常は認証もページ取得も問題ないのに、認証エラーが発生することがあった。

require 'mechanize'

url = 'http://XXXX'
username = 'XXXX'
password = 'XXXX'
agent = Mechanize.new
agent.add_auth(url, username, password)
agent.get(url)

として、以下の「Mechanize::UnauthorizedError」エラーが発生する。

`response_authenticate': 401 => Net::HTTPUnauthorized for http://XXXX -- Basic authentication failed -- available realms: XXXX HTTP BASIC LOGIN (Mechanize::UnauthorizedError)

add_authからgetまでのタイミングが早すぎるのかと間にsleepを入れたりしてみたが改善しない。また、同時刻に何度かアクセスを繰り返すと成功する場合もかなりあり、失敗する条件がはっきりしない。

このため、次のように例外設定を入れて、再試行もするようにしてみたが、

agent.add_auth(url, username, password)
flag = 0
begin
  agent.get(url)
rescue Mechanize::UnauthorizedError => e
  flag += 1
  print "認証エラー: #{flag}"
  if flag <= 5 then
    sleep 1
    retry
  end
  print "エラー:接続できませんでした。"
  exit
end

結局は、いったんアクセスエラーになるとgetだけを再試行しても効果はないらしい。

そこで、add_authも含めて再試行することにした。

flag = 0
begin
  agent.add_auth(url, username, password)
  agent.get(url)
rescue Mechanize::UnauthorizedError => e
  flag += 1
  print "認証エラー: #{flag}"
  if flag <= 5 then
    sleep 1
    retry
  end
  print "エラー:接続できませんでした。"
  exit
end

こちらであれば、認証エラー時でも再試行でアクセスできるようになった。

リンク

Leave a comment

Your comment