[Rails] Fix damn mysql adapter error..

Это пиздец.. половина четвертого утра.. а я ищу ошибки у себя в коде, когда в рельсовом адаптере актив рекорда ошибка на ошибке.

Поначалу вываливался эксепшен с логгером:

undefined method `debug' for #<Proc:xxxxxxxxx>

Казалось бы банально. Не подтянулся/подключился логгер.
Пересмотрев еще раз свой код и убедившись, что логгер там уже не присутствует, и вообще никаких puts’ов нет, словил ту же ошибку. Методом следствия было обозначено, что ошибка появляется при попытке поискать что нибудь в БД по какому нибудь значению.
Выводим полный бэектрейс и ищем откуда ноги у этого всего растут:

begin
  Model.find(params[:id])
rescue => ex
  puts "#{ex.backtrace.join("\n    ")}"
end

Любуемся кусочком простынки:

NoMethodError: undefined method `debug' for #<Proc:xxxxxxxxx>

Backtrace:
/usr/local/rvm/.../gems/activerecord-3.0.3/lib/active_record/connection_adapters/abstract_adapter.rb:201:in `rescue in log'
    /usr/local/rvm/.../gems/activerecord-3.0.3/lib/active_record/connection_adapters/abstract_adapter.rb:194:in `log'
    /usr/local/rvm/.../gems/activerecord-3.0.3/lib/active_record/connection_adapters/mysql_adapter.rb:289:in `execute'
    /usr/local/rvm/.../gems/activerecord-3.0.3/lib/active_record/connection_adapters/mysql_adapter.rb:407:in `tables'

Открываем abstract_adapter.rb на 201 строчке:

...
193         def log(sql, name)
194           name ||= "SQL"
195           @instrumenter.instrument("sql.active_record",
196             :sql => sql, :name => name, :connection_id => object_id) do
197             yield
198           end
199         rescue Exception => e
200           message = "#{e.class.name}: #{e.message}: #{sql}"
201           @logger.debug message if @logger
202           raise translate_exception(e, message)
203         end
...

Эээ… какого х.. ладно правим до необходимого нам состояния:

201  @logger.debug message if (@logger &&(@logger.class != Proc))

Прогоняю еще раз код, но ощущение, что тут еще что то всплывет не покидает.
А вот теперь уже настоящая причина бага:

ArgumentError: wrong number of arguments (1 for 0): SHOW TABLES

Backtrace:
/usr/local/rvm/.../gems/activerecord-3.0.3/lib/active_record/connection_adapters/abstract_adapter.rb:202:in `rescue in log'
    /usr/local/rvm/.../gems/activerecord-3.0.3/lib/active_record/connection_adapters/abstract_adapter.rb:194:in `log'
    /usr/local/rvm/.../gems/activerecord-3.0.3/lib/active_record/connection_adapters/mysql_adapter.rb:289:in `execute'
    /usr/local/rvm/.../gems/activerecord-3.0.3/lib/active_record/connection_adapters/mysql_adapter.rb:407:in `tables'

Открываем mysql_adapter.rb на 289 строчке:

285       def execute(sql, name = nil) #:nodoc:
286         if name == :skip_logging
287           @connection.query(sql)
288         else
289           log(sql, name) { @connection.query(sql) }
290         end
291       rescue ActiveRecord::StatementInvalid => exception
292         if exception.message.split(":").first =~ /Packets out of order/
293           raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing    .html for more information.  If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
294         else
295           raise
296         end
297       end

Бля.. как можно написать хендлер который посылает запросы с параметрами, где они не нужны.
Хотя скорее всего тут сработало, то что все было прогнано на продакшен режиме, а там при запросах к бд не посылается дополнительный `show tables`.
Я решил отказаться от логирования, как такового на данном этапе. Так, что фунция, можно сказать оптимизирована:

286         
287           @connection.query(sql)
288         
289         
290         

Сохраняем и прогоняем код. Теперь все работает.
К сожалению, мне это стоило времени сна и нервов. Увы, ни того ни другого у меня много не бывает.
з.ы. рельсы 3.0.3, руби 1.9.2.
з.ы.2. спасибо тем, кто заботится о логировании запросов, без вас я бы спал спокойно 😉
UDP:
Решение через bundler. Заменить в Gemfile строчку с рельсой на:

gem 'rails', :git => "git@github.com:Sfate/rails.git", :branch => "v3.0.3", :ref => "554656c59ab280e68522d20cd45faae6f266060c"

и прогнать разок bundle.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s