Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spree::Api 'checkouts#update' in production mode causes exception in Metal decorator #411

Open
saravanak opened this issue Feb 9, 2018 · 1 comment

Comments

@saravanak
Copy link

saravanak commented Feb 9, 2018

Calling Spree::Api checkouts#update from the sandbox in production mode causes an exception in Metal decorator. This runs fine in dev mode.

 INFO -- : [7601de39-c1f2-4ed3-ba4e-6956b99e4c95] Completed 401 Unauthorized in 218ms (ActiveRecord: 0.5ms)
FATAL -- : [7601de39-c1f2-4ed3-ba4e-6956b99e4c95]   
FATAL -- : [7601de39-c1f2-4ed3-ba4e-6956b99e4c95] NameError (undefined local variable or method `env' for #<Spree::Api::V1::CheckoutsController:0x0055f
315ceea10>):
FATAL -- : [7601de39-c1f2-4ed3-ba4e-6956b99e4c95]   
FATAL -- : [7601de39-c1f2-4ed3-ba4e-6956b99e4c95] .../bundler/gems/spree_auth_devise-541db70aeccf/app/controllers/metal_dec
orator.rb:4:in `spree_current_user'

Context

Code in question:

# For the API
ActionController::Metal.class_eval do
  def spree_current_user
    @spree_current_user ||= env['warden'].user
  end
end

Reproduction

  1. Get the latest spree source from github master. (92c6808aabec0af6fb57d91965b899c7c4fcfda1)

  2. Clone `[email protected]:saravanak/spree_8569.git

  3. Follow the readme from the above repo to run the specs.

  4. Generate the sandbox application and start the server in dev mode.

  5. The specs runs fine with the following(Bear with this failure for the moment!)

....
       expected: "payment"
            got: "complete"
     
       (compared using ==)
     # ./spec/replicate_issue_spec.rb:128:in `block (4 levels) in <top (required)>'

Finished in 24.13 seconds (files took 0.88129 seconds to load)
3 examples, 1 failure, 1 pending

  1. Copy the db/development.sqlite3 as db/production.sqlite3 and include the secret_key_base value in sandbox/environment.yml. This prepares for the prod run.

  2. Run in prod mode: RAILS_ENV=production rails s -e production

  3. 2 specs now fail:

Failures:

  1) Order update with an empty order and then taking it through to the PAYMENT state remains in the payment state when updating payment using the checkout API when requesting to stagnate
     Failure/Error: expect(response.code).to eq(200)
     
       expected: 200
            got: 500
     
       (compared using ==)
     # ./spec/replicate_issue_spec.rb:126:in `block (4 levels) in <top (required)>'

  2) Order update with an empty order and then taking it through to the PAYMENT state remains transitions to the complete state when updating payment using the checkout API
     Failure/Error: expect(response.code).to eq(200)
     
       expected: 200
            got: 500
     
       (compared using ==)
     # ./spec/replicate_issue_spec.rb:142:in `block (4 levels) in <top (required)>'

Finished in 13.72 seconds (files took 0.11461 seconds to load)
3 examples, 2 failures, 1 pending

Analysis

The issue occurs due to the following reasons:

  1. The production mode uses the config config.eager_load = true, which loads the ActionController::Metal class_eval in the app/controllers/metal_decorator.rb file.

  2. The CheckoutsController uses the before_action for update:

before_action :associate_user, only: :update
  1. This causes the try_spree_current_user > spree_current_user > @spree_current_user ||= env['warden'].user sequence to be called.

  2. According to this, rails wraps env within the request object.

Possible Fix

Change env to request.env :

ActionController::Metal.class_eval do
  def spree_current_user
    @spree_current_user ||= request.env['warden'].user
  end
end
@Dethon
Copy link

Dethon commented Feb 15, 2018

Much more complete report than mine at #400

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants