Ошибка 404 с open-uri в граблях ... что это вызывает? - PullRequest
13 голосов
/ 21 сентября 2011

У меня есть задача rake, которая извлекает данные JSON из API, анализирует их и сохраняет в базу данных:

task :embedly => :environment do
  require 'json'
  require 'uri'
  require 'open-uri'

  Video.all.each do |video|
    json_stream = open("http://api.embed.ly/1/oembed?key=08b652e6b3ea11e0ae3f4040d3dc5c07&url=#{video.video_url}&maxwidth=525")
    ruby_hash = JSON.parse(json_stream.read)
    thumbnail_url = ruby_hash['thumbnail_url']
    embed_code = ruby_hash['html']
    video.update_attributes(:thumbnail_url => thumbnail_url, :embed_code => embed_code)
  end  
end

Я получаю эту ошибку в трассировке стека, когда запускаю задачу rake иЯ понятия не имею, что вызывает это:

rake aborted!
404 Not Found
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:277:in `open_http'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:616:in `buffer_open'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:164:in `open_loop'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:162:in `catch'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:162:in `open_loop'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:132:in `open_uri'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:518:in `open'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:30:in `open'
/rubyprograms/dreamstill/lib/tasks/tasks.rake:16
/rubyprograms/dreamstill/lib/tasks/tasks.rake:15:in `each'
/rubyprograms/dreamstill/lib/tasks/tasks.rake:15
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `call'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `execute'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `each'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `execute'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:597:in `invoke_with_call_chain'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/monitor.rb:242:in `synchronize'

Есть какие-либо идеи по проблеме и как ее решить?

Ответы [ 2 ]

20 голосов
/ 21 сентября 2011

API embed.ly возвращает 404, если указанный ресурс (видео / картинка) не существует.OpenURI обрабатывает это как исключение.Чтобы поймать ошибку, вы можете сделать что-то вроде этого:

task :embedly => :environment do
  require 'json'
  require 'uri'
  require 'open-uri'

  Video.all.each do |video|
    begin
      json_stream = open("http://api.embed.ly/1/oembed?key=08b652e6b3ea11e0ae3f4040d3dc5c07&url=#{video.video_url}&maxwidth=525")
      ruby_hash = JSON.parse(json_stream.read)
      thumbnail_url = ruby_hash['thumbnail_url']
      embed_code = ruby_hash['html']
      video.update_attributes(:thumbnail_url => thumbnail_url, :embed_code => embed_code)
    rescue OpenURI::HTTPError => ex
      puts "Handle missing video here"
    end 
  end  
end

Вы также можете проверить правильность видео / URL перед запуском задачи.

1 голос
/ 21 сентября 2011

Вы не URL, кодирующий ваше video.url:

json_stream = open("...url=#{video.video_url}...")

, поэтому вы, вероятно, создаете искаженный URL, а api.embed.ly говорит вам, что он не может его найти.Например, если video.video_url равно http://a.b?c=d&e=f, то e=f будет рассматриваться как параметр для http://api.embed.ly/1/oembed, а не передаваться на http://a.b.

Возможно, вы захотите сделать это вместо:

require 'cgi'
#...
json_stream = open("...url=#{CGI.escape(video.video_url)}...")
...