【问题标题】:What condition do I check for to raise a custom error with Net::OpenTimeout execution expired error我检查什么条件以引发自定义错误 Net::OpenTimeout 执行过期错误
【发布时间】:2019-09-13 06:51:56
【问题描述】:

Open-uri 和 nokogiri 抓取我想要的站点的速度很慢,因此出现 Net::OpenTimeout 执行过期错误。我尝试使用救援编写自定义错误,但是我不知道我可以寻找什么条件来引发该自定义错误。

我尝试了很少的 if else 语句,但我真的只是猜到了如何检查我是否会收到该错误。我硬编码了一个失败的条件,从而挽救了错误。我对红宝石和自定义错误非常陌生。事实上,这是我的第一次。

    class Scrape 
    Base = 'http://www.wine.com'
   @@menu = []
    @@pages = []
    def self.index
     index_url = Base + "/list/wine/7155?sortBy=savings&pricemax=90"

        #below is where I need to check for the condition to 
        raise the error

        if   doc = Nokogiri::HTML(open(index_url))



        container = doc.css('.prodList')
        wines = container.css('.prodItem')
        wines.each do |wine|
        @@menu << {
       :link => wine.css('.prodItemInfo_link').attribute('href').value,
       :name => wine.css('.prodItemInfo_name').text,
        :rating =>  (wine.css('.averageRating_average').text.to_i) > 0  ? 
      (wine.css('.averageRating_average').text) : 'no rating',
       :price => wine.css('.productPrice_price-saleWhole').text.strip
       } 

       end
       @@menu.each do |item| 
        Bottle.new.create(item)
       end
       else  
        begin
         raise Custom_error
         rescue Custom_error => error
          puts error.message 
         end
        end
       end  

       def self.scrape_page(wine_obj)

      wine_link = wine_obj.link 

       individual_page = Base + wine_link
       docu = Nokogiri::HTML(open(individual_page))
       y = docu.css('.viewMoreModule_text')
       more = docu.css('.viewMoreModule_text')

    @@pages << { 
    :obj => wine_obj,
    :name => docu.css('.pipName').text,
       :alcohol_percent =>  y

     x = docu.css('.mobileProdAttrs').css('.prodAlcoholPercent')
     y = x.css('.prodAlcoholPercent_percent').text,

     :price => docu.css('span.productPrice_price-saleWhole').text,
     :origin => docu.css('span.prodItemInfo_originText a').text, 
     :winemaker_notes => docu.css('.viewMoreModule_text').first.text,

     :more => y[2].text,
     :rating => docu.css('span.averageRating_average').first.text
    }

    Page.create_find_by_name( @@pages.last )
     end
    def self.pages 
    @@pages 
    end
    end
    class Cli 

        def run
        puts 'loading from cyberspace'

        Scrape.index
        Bottle.make_list
        controller  
    end

    def controller
        input = ''
        response = ''
        puts '                       '
        view
        while input != 11
        response = gets.chomp.to_i
        input = "#{response}11".to_i 
        if input == 111
            menu 
        elsif input == 11
            exit 
        elsif input > 0 && input < 26 
            find_by_input(input)
        elsif input != 0 && input != 111
             error_1
        end 
    end 
    end 

     def view 
        puts "welcome to the wine bar"
        puts "================="
        puts "   W   I   N   E "
        puts "      B  A  R    "
        puts "================="
        puts "                 "
        puts "type 1 for list of wine"
        puts "                       "
        puts "type 0 to exit "
    end


    def menu 
       wines = Bottle.list   
            second_input = ''                                     
            while second_input != 0 


            puts "<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>"
            puts "type the corresponding number to view more wine info"
            puts 
    "__________________________________________________________________"
                  wines.each do |wine|
            puts "#{wine.index}) #{wine.name} #{wine.price}"
                  end
            second_input = gets.chomp.to_i 
        if second_input > 0 && second_input < 26 
            find_by_input(second_input)
        elsif second_input == 0 
            exit
            second_input = 0

        elsif second_input > 25 && second_input != 101
             error_1  
        end
            end 
       puts     <<-DOC 
                the the wine number again
                    for winemaker notes

                   DOC
    end
    def find_by_input(input)
        while input != 0
       selection = Bottle.find_by_input(input) 

        puts "NAME: #{selection.name}" 
        puts "PRICE: $#{selection.price}"
        puts "RATING: #{selection.rating}"
        puts "________________________________________"        
        puts "           type #{input} again          "
        puts "           for more info                "
        puts "           provided by the winemaker    "
        # reseting input and extending user control functionality 
            third_input = ''

            third_input = gets.chomp.to_i 

       if   third_input == selection.index

            response = Scrape.scrape_page(selection)
            view_2(response, third_input)
       elsif  input == 0
            exit 
       end
    end

    end 
    def view_2(response, old_input)

        next_input = ''
        while next_input != 0
        puts "Alcohol Percent: #{response.alcohol_percent}" 
        puts "Winemaker Notes: #{response.winemaker_notes}"
        puts "                                            "
        puts "Type #{old_input} again for more!!"

        next_input = gets.chomp.to_i

        if next_input == old_input
            input = 0
            next_input = 0
            # refacort as it puts out 88 again and should not. Also 0 is not 
    exiting with correct behavior
            # refactor so looking for "#{input}"1 to prevent the recall of 
    input
            more(response)

        end
    end
    end

    def more(response)
        puts response.more 
        puts menu
    end


    def error_1
             puts "    WHOA coder    "
             puts "type a better number!" 
    end

    def exit 
        puts <<-DOC 
        well that was fun 
        Thank you for checking out 
        my first cli program 
        DOC
    end

    end  ``` 
   ```class Page 
   attr_accessor :alcohol_percent, :price, :name, :origin, :winemaker_notes, 
    :rating, :more, :obj
    @@web_pages = [] 

    def self.create_find_by_name(hash)

    if answer = @@web_pages.find{ |obj| obj.name == hash[:name]} 
        answer 
    else
        self.new.create(hash)

    end 
    end

    def create(hash)
    hash.each do |key, value|
        self.send(("#{key}="), value) 
        end 
    save
    view_more
    end
    def view_more 
        @@web_pages.last
    end

    def save 
    @@web_pages << self 
    end

    end
    attr_accessor :link, :name, :price, :rating, :index
    @@bottles = []

    def create(hash) 
        hash.each do |key, words| 
        self.send(("#{key}="), words )
        end
        save
    end


    def save 
        @@bottles << self 
    end

    def self.make_list
        @@numbered_list = @@bottles.sort{ |x,y| x.price <=> 
    y.price}.map.with_index(1) do 
             |w,i| w.index = i  
             w
     end

    end

    def self.list 
            @@numbered_list
     end 
    def self.find_by_input(input)
        a = @@numbered_list.find{ |wine| wine.index == input}
        # puts "#{a.name} $#{a.price} rating: #{a.rating}" 
        # puts "type #{input} again for winemaker notes"
        # more = ''
        # while more != 0
        # more = gets.chomp.to_i
        #      (input == more) ? (Scrape.scrape_page(a.link)) : (self.list) 

        # end
    end



    end

    class Scrape 
    Base = 'http://www.wine.com'
    @@menu = []
    @@pages = []
    def self.index
        index_url = Base + "/list/wine/7155?sortBy=savings&pricemax=90"


        if   doc = Nokogiri::HTML(open(index_url))



        container = doc.css('.prodList')
        wines = container.css('.prodItem')
        wines.each do |wine|
       @@menu << {
       :link => wine.css('.prodItemInfo_link').attribute('href').value,
       :name => wine.css('.prodItemInfo_name').text,
        :rating =>  (wine.css('.averageRating_average').text.to_i) > 0  ? 
    (wine.css('.averageRating_average').text) : 'no rating',
       :price => wine.css('.productPrice_price-saleWhole').text.strip
       } 

       end
       @@menu.each do |item| 
        Bottle.new.create(item)
       end
    else  
        begin
         raise Custom_error
         rescue Custom_error => error
          puts error.message 
         end
        end
    end  

    def self.scrape_page(wine_obj)

    wine_link = wine_obj.link 

    individual_page = Base + wine_link
    docu = Nokogiri::HTML(open(individual_page))
    y = docu.css('.viewMoreModule_text')
    more = docu.css('.viewMoreModule_text')

    @@pages << { 
    :obj => wine_obj,
    :name => docu.css('.pipName').text,
    alcholo = docu.css('.mobileProdAttrs').css('.prodAlcoholPercent'),
    :alcohol_percent => alcholo.css('.prodAlcoholPercent_percent').text,


    :price => docu.css('span.productPrice_price-saleWhole').text,
    :origin => docu.css('span.prodItemInfo_originText a').text, 
    :winemaker_notes => docu.css('.viewMoreModule_text').first.text,

    :more => y[2].text,
    :rating => docu.css('span.averageRating_average').first.text
    }

    Page.create_find_by_name( @@pages.last )
    end
    def self.pages 
    @@pages 
    end
    end

当互联网连接中断/速度太慢时,会引发自定义错误。

【问题讨论】:

  • 您想在连接超时时引发您自己的自定义错误,而不是Net::OpenTimeoutError,对吗?

标签: ruby nokogiri custom-errors open-uri


【解决方案1】:

当抛出异常时,程序会停止其正常流程。您需要用begin..rescue 子句包围可能引发异常的代码部分,并尝试处理它、重新引发它或引发另一个异常。

在你的例子中,那将是:

begin
    Nokogiri::HTML(open(url))
rescue Net::OpenTimeoutError => e
    # log the error message if needed, raise your CustomError instead
    raise CustomError, e.message
end

您可以省略begin,并在方法末尾添加rescue 子句,ruby 会将其解释为好像整个方法体被包裹在begin..rescue 块中,如下所示:

def open_page(url)
    return Nokogiri::HTML(open(url))
rescue Net::OpenTimeoutError => e
    raise CustomError, e.message
end

【讨论】:

  • 我不确定我可以寻找什么条件来捕获错误。通过使用你的建议仍然抛出相同的错误```执行过期(Net :: OpenTimeout)2:来自/home/learn/gem/wine_bar/lib/wine_bar/scrape.rb:13:in index' 1: from /home/learn/gem/wine_bar/lib/wine_bar/scrape.rb:5:in open_page' /home/learn/gem/wine_bar/lib/wine_bar/scrape.rb:7:in `rescue in open_page': 未初始化常量 Net::OpenTimeoutError (NameError) ``
  • ``` def self.open_page(index_url) return doc = Nokogiri::HTML(open(index_url)) rescue Net::OpenTimeoutError => error raise Custom_error => error puts error.message end ` ``
  • 您收到的错误是 NameError,我想我的类名错误。尝试Net::OpenTimeout 而不是Net::OpenTimeoutError。我为这个疏忽道歉
猜你喜欢
  • 2014-05-19
  • 1970-01-01
  • 1970-01-01
  • 2015-07-14
  • 1970-01-01
  • 2011-02-13
  • 2021-10-14
  • 2022-01-08
  • 2018-12-09
相关资源
最近更新 更多