Я пишу приложение на Rails и хочу получить огромное количество информации от API, которую я передаю через объект Enumerator в виде экспорта CSV. Я хочу исправить ошибку, вызванную в Enumerator.
КОНТРОЛЛЕР: Счетчик
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
Следующие функции вызывают ошибки, но я не могу их отловить вне Enumerator:
МОДЕЛЬ: методы
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
Как я могу спасти исключение за пределами Enumerator, чтобы я мог правильно перенаправить пользователя с помощью флэш-сообщения? Как передать исключение из объекта Enumerator? Что такого в Enumerator, что не позволяет мне спасти его с помощью:
def method
Enumerator do |y|
y << BrowseScraper.get_params(_params)
end
rescue => e
Rails.logger.error "Error in Enumerator is #{e.message}"
end
Enumerator
нет ничего особенного, и вы можете спасать неперехваченные исключения в обертывающем блоке begin/rescue. В вашем методеmethod
вы спасаетеStandardError
- значение по умолчанию, когда класс исключений опущен. Вы уверены, что ваш код вызывает такое исключение или его подкласс? - person David Unric   schedule 09.09.2014StandardError
или пишу классы, основанные наStandardError
. Я даже вижу, что спасаю правильную ошибку вEnumerator
. Но я не могу спасти его вне его. Является ли это проблемой экземпляра, когда мне нужно спасти его на первом экземпляреEnumerator
? - person berfarah   schedule 09.09.2014def method; (1..10).each {|i| raise StandardError if i > 5; p i}; rescue; p 'gotcha'; end
будет печатать числа от 1 до 5, а затем будет спасена строка «попался», поскольку исключение будет спасено. - person David Unric   schedule 09.09.2014Enumerator
вы на самом деле используете. - person David Unric   schedule 09.09.2014Enumerators
, но поскольку итерация выполняетсяresponse_body
, у меня нет доступа к той части, где мне нужно ее спасти... Так что, я думаю, мне нужно сделать свой собственныйresponse_body
, который переопределяет это или что-то в этом роде. - person berfarah   schedule 09.09.2014