ZK Zhao
ZK Zhao

Reputation: 21523

Ruby on Rails: How to handle exceptions(rescue?)

I'm fetching videos' data from youtube, including general video info, and likes number of them.

The problem is that sometimes, there is no corresponding data. Maybe the video is private, or the likes number is 0.

In either case, there will report NoMethodError: undefined method 'likes' for nil:NilClass How can I handle this? I just want to ignore them and continue to the next youtube video.

I think I can use something like rescue, but I don't find many tutorial of it.

Here is my code:

client = YouTubeIt::Client.new(:dev_key => my_key)
Video.all.each do |video|
  video_info = client.video_by(video.url)
  like_number = video_info.rating.likes.to_i
  video.likes = like_number
  if video.save
    puts "#{video.title} likes: #{video.likes}"
  end
end

Upvotes: 0

Views: 260

Answers (3)

Shiva
Shiva

Reputation: 12514

In this example, the method body acts as default begin block so need of begin block

def any_method
  client = YouTubeIt::Client.new(:dev_key => my_key)
  Video.all.each do |video|
    video_info = client.video_by(video.url)
    # try tries to find the method, if not found returns nil 
    like_number = video_info.try(:rating).try(:likes).to_i
    video.likes = like_number
    if video.save
      puts "#{video.title} likes: #{video.likes}"
    end
  end
# For any type of standard errors, use rescue block    
rescue => error_object
  p 'Sorry, some error occured'
  p error_object
end

Upvotes: 0

Evgenia Karunus
Evgenia Karunus

Reputation: 11202

You should check for all possible nil values with, eg, video.nil? and corresponding conditionals. Rescuing should always be your last resort (it's slow and dirty), but, if there is no way to predict where the script will fail, you can always rescue some piece of code:

begin
  #your error-prone code
rescue
  #action you want to take in case your error-prone code raises error
end

Here is a good article on exceptions: http://www.tutorialspoint.com/ruby/ruby_exceptions.htm.

Upvotes: 0

Simone Carletti
Simone Carletti

Reputation: 176402

Rather that using the exception handling, which is slower, in this case just check for the presence of the value before calling the method.

Assuming the error is generated on the line

like_number = video_info.rating.likes.to_i

simply use

client = YouTubeIt::Client.new(:dev_key => my_key)
Video.all.each do |video|
  video_info = client.video_by(video.url)
  # here check for the presence.
  if video_info.rating
    like_number = video_info.rating.likes.to_i
    video.likes = like_number
    if video.save
      puts "#{video.title} likes: #{video.likes}"
    end
  end
end

Upvotes: 1

Related Questions