rails 3 warden NameError (uncaught throw `warden'):

我的未来我决定 提交于 2019-12-10 15:56:21

问题


this is how it should work: I log in to the admin panel, go to cars/new and fill up the fields, press create and I should have a new car in my list. www.autozeep.com

the thing is that it goes ok until I press the Create button to create the new car, server logs shows this:

NameError (uncaught throw `warden'):
  app/controllers/application_controller.rb:9:in `login_required'
  app/middleware/flash_session_cookie_middleware.rb:17:in `call'

in the development mode this is working fine, on the server in production mode it's not, it's the same code, nothing changed. for more server logs: http://pastie.org/3028350

application_controller

class ApplicationController < ActionController::Base
    protect_from_forgery

  # filter

  def login_required
    return true if authenticated?
    warden.authenticate!
  end

users_controller: http://pastie.org/3028586

I can edit a car, it works fine so the update and edit functions from cars_controller are ok, I checked the new and create functions from cars_controller but I couldn't fine anything that would give me an idea of what is going on. Cars_controller: http://pastie.org/3028452

Please help, I have this app allready running and the client si waiting for this problem only to be solved. Thank you all very much.

EDIT

NameError in CarsController#create

uncaught throw `warden'

Rails.root: /u/apps/zeepauto/releases/20111123173432
Application Trace | Framework Trace | Full Trace

app/controllers/application_controller.rb:9:in `login_required'
app/middleware/flash_session_cookie_middleware.rb:17:in `call'

ENV DUMP
...
....
rack.url_scheme: "http"
rack.version: [1, 0]
warden: Warden::Proxy:-621456458 @config={:default_strategies=>{:_all=>[:database]}, :failure_app=>UsersController, :default_scope=>:default, :scope_defaults=>{}, :intercept_401=>true}
warden.options: {:attempted_path=>"/cars", :action=>"unauthenticated"}

I get this errors only when I add new car, I can edit cars, news, contacts. everything except cars.

PROBLEM SOLVED

This problem was caused by some jquery library, I am using dynamic_form in this form so when I select car name in the next select_box appears only models for the selected car. Inspecting the problem (with my teacher, I wouldn't think of it by myself) we see that when I select car, a process called "dynamic_carmodels" is running in the logs to update the carmodels list and also at this point the session key is changed by another one, normally if session key is changed, the session that I started when I logged in is not valid anymore and that's why I get an "unauthenticated error". Still have no idea what jquery exactly was causing the problem but finally I got this solved, this was not because of the warden configuration.


回答1:


Ok I will explain to you why this exception is happening very carefully but I can't fix it for you.

Warden guards your application with a catch(:warden) block, you can see this in:

# Invoke the application guarding for throw :warden.
# If this is downstream from another warden instance, don't do anything.
# :api: private
def call(env) # :nodoc:
  return @app.call(env) if env['warden'] && env['warden'].manager != self

  env['warden'] = Proxy.new(env, self)
  result = catch(:warden) do
      @app.call(env)
  end

Your application gets called in @app.call(env) and if your application throws(:warden) it gets caught. this is how throw, catch works, here is an example:

def authenticate!()
  throw :warden
end

catch(:warden) do
  puts "Calling authenticate!" 
  authenticate!() 
end

puts "Succesfully called authenticate!"
#outside of catch(:) guard
authenticate!()
puts "this never gets executed"

If I execute this it will do:

 ruby exc.rb 
 Calling authenticate!
 Succesfully called authenticate!
 exc.rb:2:in `throw': uncaught throw :warden (ArgumentError)
    from exc.rb:2:in `initialize!'
    from exc.rb:12:in `<main>'

As you can see, the 2nd time I called authenticate! I was outside the catch(:warden) block, therefore when I throw :warden there was no catch block to catch it, exception ocurred.

This is what is happening to you, look at warden#authenticate!:

def authenticate!(*args)
   user, opts = _perform_authentication(*args)
   throw(:warden, opts) unless user
   user
end

See the throw(:warden, opts) ? If that throw is outside the catch(:warden) block the exception is raised. Warden is supposed to guard your whole app in the catch block, so that you can throw :warden at any point. But for some reason this is not happening on zeepauto.

Your problem is that warden is not properly setup(there is no config/initializers/warden.rb) and call (env)so your catch(:warden) guard is never set.

Your answer is here: https://github.com/hassox/warden/wiki/Setup

Just work yourself through the setup. You can test on your dev environment by throwing a :warden at any time. Just write a test like:

it "warden should catch the throw :warden at any point" do
  throw(:warden)
end

If you want to get this thing faster, just get a pro account in railscasts.com and watch: http://railscasts.com/episodes/305-authentication-with-warden that episode will guide you through the setup.



来源:https://stackoverflow.com/questions/8540695/rails-3-warden-nameerror-uncaught-throw-warden

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!