我正在Rails中编写一个应用程序,我希望从API中获取大量信息 - 我将通过Enumerator对象作为CSV导出进行流式处理。我想解救在枚举器中调用的错误。
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
以下函数引发错误,但我无法在枚举器之外捕获它们:
def self.get_params
response = open(url)
raise if response.code != 200
end
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
答案 0 :(得分:1)
我想我已经弄明白这里发生了什么。在Enumerator中编写代码时,该块实际上并未在Enumerator中执行。因此,如果我在枚举器中添加rescue
,则无关紧要。
这是因为Enumerator中的|y|
实际上是一个yielder对象,它会产生屈服(更多关于Enumerator documentation或Enumerator::Yielder documentation。
你必须事先救出东西。