【Rails+Devise】ArgumentError: SMTP From address may not be blank: nil
最初に
開発環境では動くけれど、テストや本番環境では動かず原因がなかなかわからず大変だった。
色々原因はあったけれど、環境変数の乱用が1番よくなかった気がする。
あと、Mailgunの導入でそっち関係のエラーだと勘違いして、実際はDevise側の設定で、問題を正常に切り分けられていなかった。
謎のエラー
「ユーザー登録」のボタンをクリックすると、メールアドレス確認用のメールを送る。
この際に、ローカルではエラーが起きなかったが、CI環境と本番環境でエラーが起きていた。
ArgumentError: SMTP From address may not be blank: nil
エラー文はこのように書かれている。何らかの原因でどこかでnil
になってしまい、エラーになっているようだ。
SMTP From address ?
テスト環境でのエラー
rails test:all
コマンドを打って、システムテストをしているときに生じたエラー
Rack app ("POST /users" - (127.0.0.1)): #<ArgumentError: SMTP From address may not be blank: nil> E Error: SignUpTest#test_sign_up: ArgumentError: SMTP From address may not be blank: nil
本番環境(Heroku)でのエラー
heroku logs -t
2021-07-23 app[web.1]: I, [2021-07-23 #4] INFO -- : Rendered devise/mailer/confirmation_instructions.html.erb (Duration: 2.0ms | Allocations: 351) 2021-07-23 app[web.1]: I, [2021-07-23 #4] INFO -- : Delivered mail asdfghjkl1234567890@asdfghjkl1234567890.mail (753.9ms) 2021-07-23app[web.1]: I, [2021-07-23 #4] INFO -- : Completed 500 Internal Server Error in 801ms (ActiveRecord: 8.1ms | Allocations: 7800) 2021-07-23 app[web.1]: F, [2021-07-23 #4] FATAL -- : 2021-07-23 app[web.1]: ArgumentError (SMTP From address may not be blank: nil): 2021-07-23 app[web.1]: 2021-07-230 app[web.1]: mail (2.7.1) lib/mail/check_delivery_params.rb:13:in `check_from'
原因
config/initializers/devise.rb
config.mailer_sender = ENV['SMTP_MAIL_ADRESS']
開発環境・本番環境でメールの設定が別々だからとか、そんな理由で適当に環境変数を設定した。
(まぁ、Deviseの設定ファイルについてもちゃんとした理解をしていなかったし、そんな設定をしたことも忘れていた)
で、ローカルでは環境変数をセットしていたが、CI環境や本番環境では環境変数がセットされておらず、ENV['SMTP_MAIL_ADRESS']
がnil
を返してしまい、Rails内でnil
が渡されていた。
勘違い
最初は、Deviseの初期設定だと思っておらず、Mailgunの設定やRailsのmailerの基本設定を疑っていた。
app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base default from: 'foo@bar.com' layout 'mailer' end
対策
環境変数を使ってもいいと思うが使ったとしても、環境変数というキーがなかったエラーを起こしてあげれば、どこが問題でエラーが起きているのか浅いところでわかるので、問題の切り分けがわかりやすくなったように思う。
ENV.fetch('SMTP_MAIL_ADRESS')
上記のような感じで、fetch
メソッドを使ったりしたらいいように思う。
【余談】開発環境で環境変数が更新されないバグ?
バグを解決する際に、本番環境でしかエラーが起きずMailgun絡みの問題だと思っていた。
(このとき、CIで同じエラーが起きることに気づいていなかった)
とりあえず、開発環境でエラーを起こした方が楽そうなので、開発環境でもMailgunを使ってみることにした。
その際に、dotenv-rails
というgemを使って、.env
ファイルに環境変数を書き込んでいたが、Railsを立ち上げ直しても環境変数が更新されないことがあった。
これについては、spring stop
コマンドを打つと、環境変数が更新された。
Railsで持っているcredentialsの機能を使った方がいいかもしれない。
【参考】 Qiita: Railsで環境変数の変更が反映されないときはspring stopを試す
最後に
とりえあえず解決してよかった。