rails 3 warden NameError (неперехваченный бросок `надзирателя'):

вот как это должно работать: я захожу в админку, захожу в cars/new и заполняю поля, нажимаю создать и у меня в списке должна быть новая машина. www.autozeep.com

дело в том, что все идет нормально, пока я не нажму кнопку «Создать», чтобы создать новую машину, логи сервера показывают это:

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

в режиме разработки это работает нормально, на сервере в режиме производства - нет, код тот же, ничего не изменилось. дополнительные журналы сервера: 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

Я могу редактировать автомобиль, он работает нормально, поэтому функции обновления и редактирования из cars_controller в порядке, я проверил новые и создал функции из cars_controller, но я не смог найти ничего, что дало бы мне представление о том, что происходит. Cars_controller: http://pastie.org/3028452

Пожалуйста, помогите, у меня это приложение уже запущено, и клиент ждет, пока эта проблема будет решена. Всем большое спасибо.

ИЗМЕНИТЬ

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"}

Я получаю эти ошибки только когда добавляю новую машину, я могу редактировать машины, новости, контакты. все, кроме автомобилей.

ПРОБЛЕМА РЕШЕНА

Эта проблема была вызвана какой-то библиотекой jquery, я использую dynamic_form в этой форме, поэтому, когда я выбираю имя автомобиля в следующем поле select_box, отображаются только модели для выбранного автомобиля. Исследуя проблему (с моим учителем, я бы сам об этом не подумал), мы видим, что когда я выбираю автомобиль, в журналах запускается процесс под названием «dynamic_carmodels» для обновления списка моделей автомобилей, а также в этот момент ключ сеанса заменяется другим, обычно, если ключ сеанса изменяется, сеанс, который я начал при входе в систему, больше недействителен, и поэтому я получаю «неаутентифицированную ошибку». До сих пор не знаю, что именно jquery вызывало проблему, но, наконец, я решил эту проблему, это было не из-за конфигурации надзирателя.


person rmagnum2002    schedule 16.12.2011    source источник
comment
это в github.com/rmagnum2002/zeepauto   -  person rmagnum2002    schedule 19.12.2011
comment
Похоже, это зависимость от rails_warden, его должен подобрать упаковщик, но попробуйте.   -  person daniel    schedule 19.12.2011
comment
спасибо, сейчас попробую. Я разговариваю со службой поддержки, чтобы попробовать то, что вы предлагаете.   -  person rmagnum2002    schedule 19.12.2011
comment
Я бы очень рекомендовал использовать Devise, если вы смотрите на Warden, он устраняет так много проблем...   -  person Neil Middleton    schedule 19.12.2011
comment
Уорден в порядке, он просто никогда не настраивался должным образом. Devise требует еще больше работы   -  person daniel    schedule 19.12.2011
comment
Дэниел, могу я связаться с вами через скайп или любой другой мессенджер, чтобы закончить это дело быстрее. Пожалуйста, я бы отдал все свои баллы за это :)   -  person rmagnum2002    schedule 20.12.2011
comment
только что написал вам подробное объяснение проблемы. Если вы понимаете, почему это происходит, исправить это должно быть легко.   -  person daniel    schedule 20.12.2011
comment
Завтра посмотрю и получу ответ. Большое спасибо за Вашу помощь.   -  person rmagnum2002    schedule 21.12.2011


Ответы (1)


Хорошо, я очень осторожно объясню вам, почему это исключение происходит, но я не могу это исправить.

Warden защищает ваше приложение с помощью блока catch(:warden), вы можете увидеть это в:

# 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

Ваше приложение вызывается в @app.call(env), и если ваше приложение бросает (:warden), оно перехватывается. вот как работает throw, catch, вот пример:

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"

Если я выполню это, это будет сделано:

 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>'

Как вы видите, во второй раз я вызвал authentication! Я был вне блока catch(:warden), поэтому, когда я выбрасывал :warden, не было блока catch для его перехвата, возникало исключение.

Вот что с тобой происходит, посмотри на warden#authenticate!:

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

См. throw(:warden, opts)? Если этот бросок находится за пределами блока catch(:warden), возникает исключение. Предполагается, что Warden охраняет все ваше приложение в блоке catch, чтобы вы могли бросить :warden в любой момент. Но на zeepauto этого почему-то не происходит.

Ваша проблема в том, что надзиратель не настроен должным образом (нет config/initializers/warden.rb) и call (env) поэтому ваш охранник поймать (: надзиратель) никогда не установлен.

Ваш ответ здесь: https://github.com/hassox/warden/wiki/Setup

Просто проработайте настройку самостоятельно. Вы можете протестировать свою среду разработки, создав :warden в любое время. Просто напишите тест, например:

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

Если вы хотите получить это быстрее, просто заведите профессиональную учетную запись на railscasts.com и смотрите: http://railscasts.com/episodes/305-authentication-with-warden этот эпизод поможет вам выполнить настройку.

person daniel    schedule 18.12.2011
comment
У меня есть manager.rb и код в приложении на сервере, его копия здесь github.com/rmagnum2002/zeepauto/blob/master/vendor/bundle/ruby/ а как насчет код обратной трассировки? где я должен положить его? - person rmagnum2002; 19.12.2011
comment
Я имею в виду просто заменить warden.authenticate! с этим кодом, чтобы мы могли регистрировать сообщения обратной трассировки. - person daniel; 19.12.2011
comment
извините, вы имеете в виду здесь github.com/rmagnum2002/zeepauto/blob /мастер/приложение/контроллеры/ ? надзиратель.подтвердить! заменить кодом обратной трассировки? Я никогда не использовал такие трюки раньше, и я не знаю, как это сделать правильно. - person rmagnum2002; 19.12.2011
comment
Это просто обертка вызова, который throws(:warden) для перехвата исключения NameError, а затем использование обработчика исключений для обратной трассировки. Я сделал ошибку в запросе на вытягивание, удалите повторяющийся код. - person daniel; 19.12.2011
comment
не могли бы вы написать, пожалуйста, более подробный учебник по этому решению? Я действительно понятия не имею (и персонал службы поддержки тоже), куда поместить этот код и как он должен выглядеть, будьте так любезны, вытащите это, пожалуйста. - person rmagnum2002; 19.12.2011
comment
pastie.org/3038504 вот журналы сервера, которые я получил от сотрудников службы поддержки, это может помочь увидеть где проблема? - person rmagnum2002; 19.12.2011
comment
@search в какой-то момент равен нулю, у вас есть нулевой указатель там, где вы его не ожидали. В вашем контроллере, когда вы выполняете Car.search(params[:search]) возвращается ноль, и вы никогда не проверяете - person daniel; 19.12.2011
comment
Хорошо, я посмотрел на ваше приложение, вы вообще не настроили надзирателя, прочитайте документы ... вам нужен какой-то обработчик при сбое аутентификации, и вам нужно сказать об этом надзирателю. - person daniel; 19.12.2011
comment
Если да, то как можно объяснить тот факт, что я могу добавлять новости и делать все остальное в админке, кроме добавления автомобилей. Это тот же фильтр login_required для новостей и автомобилей. Я согласен с тем, что я неправильно настроил надзирателя, но я ожидал, что, по крайней мере, это будет работать так же, как на моем компьютере для разработки. - person rmagnum2002; 19.12.2011
comment
ну, я не знаю, возможно, вы уже прошли аутентификацию или что-то в этом роде, чтобы надзирателю никогда не приходилось вызывать неудавшееся приложение. Не беда, настройте его правильно и все должно работать - person daniel; 19.12.2011
comment
Привет, Дэниел. При использовании rails_warden вы говорите, что инициализатор для Warden::Manager не требуется? Я использую блок RailsWarden::Manager, указанный выше, но продолжаю получать неперехваченные исключения throw :warden. - person aceofspades; 19.12.2011
comment
@daniel: к сожалению, я все еще получаю исключения. Кстати, разве вы не сериализуете там весь класс записи? Мне пришлось изменить свой на record.class.name. - person aceofspades; 20.12.2011
comment
Дэниел, могу я связаться с вами через скайп или любой другой мессенджер, чтобы закончить это дело быстрее. Пожалуйста, я бы отдал все свои баллы за это - person rmagnum2002; 20.12.2011
comment
Смотрите отредактированный вопрос, это была не проблема надзирателя, ну, это было потому, что ключ сеанса был изменен какой-то библиотекой js, пока я заполнял форму. Спасибо за ваше время и попытку помочь. - person rmagnum2002; 22.12.2011