LoginSignup
0
0

More than 1 year has passed since last update.

railsでloggerをActiveSupport::Loggerではなく独自のLoggerを使っている場合にsprockets-railsでNoMethodErrorが発生する問題の解消

Posted at

sprockets-railsNoMethodErrorが発生したので原因の解説と対策を書いておきます。

発生するケース

以下の3つの条件が重なる場合に例外が発生します。

  • app.config.assets.quiettrue(デフォルト値)
  • assetsを参照する
  • 例えば以下の様に開発環境は独自のloggerを使っておりActiveSupport::LoggerではなくLoggerクラスのインスタンスを設定している
config/development.rb
Rails.application.configure do
  config.logger = Logger.new(STDOUT)
end

この状態でassetsを参照しているページにリクエストを行うと以下の様にNoMethodErrorが発生します。

#<NoMethodError: undefined method `silence' for #<Logger:0x0000ffff792b3418 @level=0, @progname=nil, @default_formatter=#<Logger::Formatter:0x0000ffff792b2fb8 @datetime_format=nil>, @formatter=nil, @logdev=#<Logger::LogDevice:0x0000ffff792b29f0 @shift_period_suffix=nil, @shift_size=nil, @shift_age=nil, @filename=nil, @dev=#<IO:<STDOUT>>, @binmode=false, @mon_data=#<Monitor:0x0000ffff792b2950>, @mon_data_owner_object_id=8980>>

::Rails.logger.silence { @app.call(env) }

原因

config.loggerではLoggerクラスのインスタンスを指定できますが、Loggerクラスのインスタンスにはsilenceメソッドが定義されていないためです。

そのためsprockets-railsで例外が発生していました。

sprockets-rails/lib/sprockets/rails/quiet_assets.rb
 def call(env)
    if env['PATH_INFO'] =~ @assets_regex
      ::Rails.logger.silence { @app.call(env) }
    else
      @app.call(env)
    end
end

対応

以下のいずれかの対応することで回避可能です。

 1. config.loggerに指定する値はActiveSupport::Loggerのインスタンスに変更する

config/development.rb
Rails.application.configure do
-  config.logger = Logger.new(STDOUT)
+  config.logger = ActiveSupport::Logger.new(STDOUT)
end

 2. app.config.assets.quietfalseに設定する

config/development.rb
Rails.application.configure do
+ config.assets.quiet = false
  config.logger = Logger.new(STDOUT)
end

FYI

このケースに遭遇してエラーが発生する場合にNoMethodErrorではなく独自の例外発生とエラーメッセージを出力する対応がされていました。

def raise_logger_silence_error
  error = "You have enabled `config.assets.quiet`, but your `Rails.logger`\n"
  error << "does not use the `LoggerSilence` module.\n\n"
  error << "Please use a compatible logger such as `ActiveSupport::Logger`\n"
  error << "to take advantage of quiet asset logging.\n\n"

  raise LoggerSilenceError, error
end

当記事の投稿時点ではmasterブランチにはマージされていましたがこちらのコミットが含まれているリリースバージョンはまだリリースされていません。

環境

$ rails -v
Rails 7.0.4.3

$ bundle info sprockets-rails
* sprockets-rails (3.4.2)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0