settheline
settheline

Reputation: 3383

Handle failure in rake task without aborting

I have this rake task:

desc "get product image urls from ItemMaster"
task :get_product_image_urls => :environment do
    require 'item_master'
    ItemMaster.get_image
end

It calls this API method that iterates over several thousand database items like so:

class ItemMaster
    include HTTParty
format :xml

base_uri 'https://api.myapi.com/v2'


def self.get_image
    @items = Item.all 
    @items.each do |item|
        response = get("/item?upc=#{item.upc}&epl=100&ef=png", :headers => {"username" => "myname", "password" => "mypass"})
        image_link = response["items"]["item"]["media"]["medium"]["url"]
        item_image = ItemImage.where(:upc => item.upc).first_or_create
        item_image.update_attributes(:url => "#{image_link}")
    end
  end
end

The rake task starts up when I call it, until it hits this error about 22 items in:

undefined method `[]' for nil:NilClass
/Users/name/Rails/SG/lib/item_master.rb:12:in `block in get_image'
/Users/name/Rails/SG/lib/item_master.rb:10:in `each'
/Users/name/Rails/SG/lib/item_master.rb:10:in `get_image'
/Users/name/Rails/SG/lib/tasks/get_product_image_urls.rake:4:in `block in <top (required)>'
/Users/name/.rvm/gems/ruby-1.9.3-p429/bin/ruby_noexec_wrapper:14:in `eval'
/Users/name/.rvm/gems/ruby-1.9.3-p429/bin/ruby_noexec_wrapper:14:in `<main>'

Line 12 is this guy: image_link = response["items"]["item"]["media"]["medium"]["url"] so I'm thinking that probably a url is missing in the api and it's causing the rake task to fail. Is there a way to move past an error like this and continue on with the rest of the rake task? Thanks in advance!

Upvotes: 0

Views: 728

Answers (1)

pdobb
pdobb

Reputation: 18037

The ItemMaster.get_image method will need to be edited to either not create the exception condition in the first place, or to rescue on a proper exception and move on. For more on exception handling: http://www.tutorialspoint.com/ruby/ruby_exceptions.htm

An example would be:

def self.get_image
    @items = Item.all 
    @items.each do |item|
        response = get("/item?upc=#{item.upc}&epl=100&ef=png", :headers => {"username" => "myname", "password" => "mypass"})
        begin
          image_link = response["items"]["item"]["media"]["medium"]["url"]
          item_image = ItemImage.where(:upc => item.upc).first_or_create
          item_image.update_attributes(:url => "#{image_link}")
        rescue NoMethodError => ex
          logger.error "Failed to locate image link ..." # Customize this to your liking
        end
    end
  end
end

For extra goodness, consider handling the code for each item within a separate method so you can isolate responsibility for handling item-related code within the Item model itself!

Upvotes: 1

Related Questions