如何从枚举器内部抢救异常?

时间:2014-09-08 23:56:30

标签: ruby-on-rails ruby exception enumerator rescue

我正在Rails中编写一个应用程序,我希望从API中获取大量信息 - 我将通过Enumerator对象作为CSV导出进行流式处理。我想解救在枚举器中调用的错误。

CONTROLLER:枚举器

def csv_lines( url )
    Enumerator.new do |y|
        per_page = 200

        # Parse parameters and get shelf information
        _params = BrowseScraper.get_params(url)
        shelf = BrowseScraper.get_preso( _params, 0 )
            total_items = shelf['response']['total_results']['all'].to_i
            total_pages = ( total_items / per_page.to_f ).ceil
            shelf_info  = BrowseScraper.crawl_ids( shelf['response']['query']['category'] )

        y << BrowseScraper.csv_header(url, shelf_info, total_items, ["Tool ID", "Name", "Price", "URL"])

        total_pages.times { |i| y << BrowseScraper.csv_body( _params, per_page, i+1) }
    end
end

以下函数引发错误,但我无法在枚举器之外捕获它们:

MODEL:方法

def self.get_params
  response = open(url)
  raise if response.code != 200
end

CONTROLLER:显示

def export
    url = params[:url]
    raise StandardError, "Please enter a Browse URL below" if !url || url.empty?

    respond_to do |format|
        format.csv do
            render_csv(url)
        end
        format.html { render_csv(url) }
    end
rescue => e
    flash[:error] = e.message
    redirect_to scraper_path
end

private
    def render_csv( url )
        set_file_headers
        set_streaming_headers

        response.status = 200

        # Rails should iterate this enumerator
        self.response_body = csv_lines(url)
    end

    def set_file_headers( name = "browse_export" )
        headers["Content-Type"] ||= 'text/csv'
        headers["Content-Disposition"] = "attachment; filename=\"#{name}.csv\""
        headers["Content-Transfer-Encoding"] = "binary"
        headers["Last-Modified"] = Time.now.ctime.to_s
    end

    def set_streaming_headers
        #nginx doc: Setting this to "no" will allow unbuffered responses suitable for Comet and HTTP streaming applications
        headers['X-Accel-Buffering'] = 'no'
        headers["Cache-Control"] ||= "no-cache"
        headers.delete("Content-Length")
    end

拯救export中引发的错误。在Enumerator中解决错误(例如:

Enumerator do |y|
  begin
    y << BrowseScraper.get_params(_params)
  rescue => e
    Rails.logger.error "Failed to get parameters: #{e.message}"
  end
end

如何在枚举器外部抢救异常,以便我可以使用flash消息正确地重定向用户?如何从Enumerator对象中传递异常?什么是关于不让我救援它的枚举器:

def method
    Enumerator do |y|
        y << BrowseScraper.get_params(_params)
    end
rescue => e
    Rails.logger.error "Error in Enumerator is #{e.message}"
end

1 个答案:

答案 0 :(得分:1)

我想我已经弄明白这里发生了什么。在Enumerator中编写代码时,该块实际上并未在Enumerator中执行。因此,如果我在枚举器中添加rescue,则无关紧要。

这是因为Enumerator中的|y|实际上是一个yielder对象,它会产生屈服(更多关于Enumerator documentationEnumerator::Yielder documentation

你必须事先救出东西。