shopify-api-ruby: activeresource 5.1.0 seems to breaking this gem

NoMethodError: undefined method `path' for nil:NilClass (Most recent call first)
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 701 in prefix
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 711 in prefix_source
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1126 in prefix_parameters
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1141 in block in split_options
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1139 in each
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1139 in split_options
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1661 in split_options
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1439 in load
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1181 in initialize
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1462 in new
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1462 in block in load
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1447 in each
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1447 in load
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1181 in initialize
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1462 in new
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1462 in block in load
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1447 in each
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1447 in load
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1181 in initialize
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1108 in new
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1108 in instantiate_record
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 1097 in find_single
File /app/vendor/bundle/ruby/2.5.0/gems/activeresource-5.1.0/lib/active_resource/base.rb line 984 in find

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 2
  • Comments: 36 (10 by maintainers)

Commits related to this issue

Most upvoted comments

@marisveide and @andrisbriedis way to keep digging here 💪 Great catch!

@marisveide Thank you for you ongoing investigating and reporting on this 👍

@marisveide we came to the same conclusion. Seems to mostly happen on ShopifyAPI::Order and I do believe this started happening when we moved to a multi-threaded env.

Also, we hadn’t seen this error since Feb until about 2 weeks ago and it randomly came back 😞 That said I did some more digging around this and here’s what I came up with:

In our app every time we need to activate a Session we do it from a single class:

class ShopifyApiGateway
  def self.activate(store)
    ShopifyAPI::Session.setup(
      api_key: 'SHOPIFY_API_KEY',
      secret: 'SHOPIFY_SHARED_SECRET'
    )
    session = ShopifyAPI::Session.new(
      domain: store.domain,
      token: store.token,
      api_version: 'VERSION'
    )
    ShopifyAPI::Base.activate_session(session)
  end
end

This allows us invocation in our workers like:

def initialize(id)
  @store = ShopifyStore.find(id)
  ShopifyApiGateway.activate(@store)
end

That typically how we set up the session so then back to your find about the site.path - when I’m looking in where site.path get’s define here: https://github.com/rails/activeresource/blob/v5.1.0/lib/active_resource/base.rb#L701

It leads to believe that it’s getting set as a class level getter. Which then leads to our particular case I believe that would fall to the ShopifyAPI::Base here: https://github.com/rails/activeresource/blob/v5.1.0/lib/active_resource/base.rb#L444

When I dig further into the backtrace I see that activate_session looks like:

def activate_session(session)
  raise InvalidSessionError.new("Session cannot be nil") if session.nil?
  self.site = session.site
  self.headers.merge!('X-Shopify-Access-Token' => session.token)
  self.api_version = session.api_version
end

This then sets the class site from the site on the session that we instantiated earlier. Which is interesting because that class has a method site that returns a string only. https://github.com/Shopify/shopify_api/blob/master/lib/shopify_api/session.rb#L130

def site
  "https://#{domain}"
end

Which is being fed in my case from the initial class I set up.

session = ShopifyAPI::Session.new(
  domain: store.domain,
  token: store.token,
  api_version: 'VERSION'
)

This is unfortunately where I got stumped. Not sure where to go from here. I’m not sure how path is ever defined really…

Anyone have thoughts?