Search code examples
ruby-on-railssidekiq

Sidekiq. How to catch the error in production?


I have few workers that have no errors in log. But same code in production from time to time show errors. It's not critical, but I want to understand what is the difference and how to catch and fix the errors. Here part of log with error:

2016-01-18T16:34:10.725Z 535 TID-otb5ze3fo TopUpdateWorker JID-73c584ed6fec322784d67796 INFO: start
2016-01-18T16:34:10.725Z 535 TID-otb5ze3fo TopUpdateWorker JID-73c584ed6fec322784d67796 INFO: Things are happening.
2016-01-18T16:34:10.824Z 535 TID-otb5ze3fo TopUpdateWorker JID-73c584ed6fec322784d67796 INFO: fail: 0.099 sec
2016-01-18T16:34:10.824Z 535 TID-otb5ze3fo WARN: {"class"=>"TopUpdateWorker", "args"=>[], "retry"=>3, "queue"=>"default", "jid"=>"73c584ed6fec322784d67796", "created_at"=>1453134850.724368, "enqueued_at"=$
2016-01-18T16:34:10.824Z 535 TID-otb5ze3fo WARN: TypeError: no implicit conversion of nil into Array
2016-01-18T16:34:10.824Z 535 TID-otb5ze3fo WARN: /var/www/vkgazer/code/lib/modules/common_mods.rb:27:in `+'
/var/www/vkgazer/code/lib/modules/common_mods.rb:27:in `get_request'
/var/www/vkgazer/code/app/models/post.rb:170:in `top_post_updater'
/var/www/vkgazer/code/app/workers/top_update_worker.rb:9:in `perform'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/processor.rb:150:in `execute_job'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/processor.rb:132:in `block (2 levels) in process'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/middleware/chain.rb:127:in `block in invoke'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/middleware/server/active_record.rb:6:in `call'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/middleware/server/retry_jobs.rb:74:in `call'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/middleware/server/logging.rb:11:in `block in call'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/logging.rb:30:in `with_context'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/middleware/server/logging.rb:7:in `call'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/middleware/chain.rb:132:in `call'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/middleware/chain.rb:132:in `invoke'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/processor.rb:127:in `block in process'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/processor.rb:166:in `stats'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/processor.rb:126:in `process'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/processor.rb:79:in `process_one'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/processor.rb:67:in `run'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/util.rb:16:in `watchdog'
/var/www/vkgazer/code/vendor/bundle/ruby/2.2.0/gems/sidekiq-4.0.1/lib/sidekiq/util.rb:24:in `block in safe_thread'

The error is always in this string. Here is the code:

 def get_request(code) #
    i = 0
    result = []
    while i < code.size #
      part_code = code.slice(i, 25)
      if part_code.size >1
        str_code = part_code.join(',')
      else
        str_code = part_code[0]
      end
      url='https://api.x.com/method/execute'
      uri = URI.parse(url)
      parameters =  {'access_token' => '00',
                    'code' => "return [#{str_code}];", 'v' => '2'}
      response = Net::HTTP.post_form(uri, parameters) # 
      result = result + JSON.parse(response.body)['response'] #here is error
      i += 25
      sleep 0.35
    end
    result #
  end

Here I send requests to API and sum all responses in result. And one more thing in development I have durations of jobs less then 10 sec, but in production it can be 160 sec. My computer is better then server?


Solution

  • So any time that your response.body contains an "empty" response, like "{}" or if it's just missing the 'response' element, then JSON.parse(response.body)['response'] will be nil and so your code is trying to do:

    result + nil
    

    ...and you're getting this error. Probably the best way around this is something like this:

    result = result + ( JSON.parse(response.body)['response'] || [] )