2016-10-10 5 views
0

Я использую Rails 4.2.7. В настоящее время Im»запрашивает веб-страницы через прокси-сервер SOCKS, как такВ RoR, как мне восстановить из «Не удалось открыть TCP-соединение ... (общий отказ сервера SOCKS)»?

begin 
    ... 
    res1 = Net::HTTP.SOCKSProxy('127.0.0.1', 50001).start(uri.host, uri.port) do |http| 
     puts "launching #{uri}" 
     resp = http.get(uri) 
     status = resp.code 
     content = resp.body 
     content_type = resp['content-type'] 
     content_encoding = resp['content-encoding'] 
    end 
    ... 
rescue OpenURI::HTTPError => ex 
    ... 
rescue SocketError, Net::OpenTimeout, Zlib::BufError => e 
    ... 
end 

и иногда я получаю следующую ошибку ..

Error during processing: Failed to open TCP connection to otherwebsite.com:80 (general SOCKS server failure) 
/Users/mikeb/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:882:in `rescue in block in connect' 
/Users/mikeb/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:879:in `block in connect' 
/Users/mikeb/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/timeout.rb:91:in `block in timeout' 
/Users/mikeb/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/timeout.rb:101:in `timeout' 
/Users/mikeb/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:878:in `connect' 
/Users/mikeb/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:863:in `do_start' 
/Users/mikeb/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:852:in `start' 
/Users/mikeb/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:584:in `start' 
/Users/mikeb/Documents/workspace/runtrax/app/helpers/webpage_helper.rb:96:in `get_content' 
/Users/mikeb/Documents/workspace/runtrax/app/helpers/webpage_helper.rb:32:in `get_url' 
/Users/mikeb/Documents/workspace/runtrax/app/services/onlinerr_race_finder_service.rb:42:in `get_race_list' 
/Users/mikeb/Documents/workspace/runtrax/app/services/abstract_race_finder_service.rb:26:in `process_data' 
/Users/mikeb/Documents/workspace/runtrax/app/services/run_crawlers_service.rb:18:in `block in run_all_crawlers' 
/Users/mikeb/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/relation/delegation.rb:46:in `each' 
/Users/mikeb/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7.1/lib/active_record/relation/delegation.rb:46:in `each' 

Как поймать эту ошибку и повторите мою просьбу?

Редактировать: Как мой вопрос отличается от того, что было задано? Дубликат ссылается на ошибку буфера, этот quesiton имеет дело с ошибкой сокета.

+1

спасая 'StandardError' должен делать я полагаю, исключение приходит из [здесь] (https://github.com/ruby/ruby/blob/v2_3_1/lib/net /http.rb#L882), который ререйзирует любые броски «TCPSocket.open», которые, как я полагаю, должен быть дочерним элементом «StandardError», поэтому просто «начинаем»; #body вашего кода; rescue => e; #your логический конец повтора должен делать – bjhaid

+0

Возможный дубликат [Как уловить ошибку «Ошибка во время обработки: ошибка буфера» в Ruby при получении веб-страницы?] (http://stackoverflow.com/questions/39919198/how- do-i-catch-the-error-in-processing-buffer-error-in-ruby-when-getting) –

+0

@bjhaid, согласно моему комментарию к ответу, «rescue => e» просто ломает любую общую ошибку. Я хочу только уловить конкретную ошибку, упомянутую в моем вопросе, и повторить попытку. СкоттБартель, как эти вопросы похожи друг на друга? Это две совершенно разные ошибки. –

ответ

2

Вы можете retry:

retries = 0 
begin 
    res1 = Net::HTTP.SOCKSProxy('127.0.0.1', 50001).start(uri.host, uri.port) do |http| 
    puts "launching #{uri}" 
    resp = http.get(uri) 
    status = resp.code 
    content = resp.body 
    content_type = resp['content-type'] 
    content_encoding = resp['content-encoding'] 
    end 
rescue => e 
    retries += 1 
    if retries < 3 
    retry # <-- Jumps to begin 
    else 
    # Error handling code, e.g. 
    logger.warn "Couldn't connect to proxy: #{e}" 
    end 
end 
+0

Но здесь вы просто ловите общую ошибку. Я только хочу иметь дело с ошибкой, указанной в моем вопросе. Если возникают другие ошибки, я не хочу повторять попытку. –

+0

@Mike Я думаю, вы можете принять поведение библиотеки HTTP в качестве открытого интерфейса. Он не различает исключения. Быть на более высоком уровне, вам тоже не нужно. Я думаю, это может быть что-то вроде таймаута, общей ошибки соединения или чего-то еще. Вам нужно обрабатывать каждый из этих случаев ошибок по-разному? Мое предположение было бы ['SocketError'] (http://ruby-doc.org/stdlib-2.3.1/libdoc/socket/rdoc/SocketError.html) –

+0

Привет, я редактировал свой вопрос, чтобы отразить тот факт, что я дал вылавливая «SocketError» выстрел, но выполнение не переходит к этой ветке, когда вызывается erorr в моем вопросе. –