【Rails】404、500エラーをハンドリング(slack通知も)
エラーハンドリングのメモが残ってたから、体系的な内容に纏めてみた。
どうせなのでコッチに移しておく。
エラーハンドリングをする
- 404エラー時は、404エラー用のテンプレートを表示させる。
- 500エラー時は例外(エラー)クラス、エラーメッセージ 、バックトレースをログに出力させ、500エラー用のテンプレートを表示させる。
application_controller.rb
にエラー時の設定を書く
→どんなページを表示するか、どんなログを残すかなど。
(application_controller.rb) class ApplicationController < ActionController::Base rescue_from ActiveRecord::RecordNotFound, with: :render_404 rescue_from StandardError, with: :render500 def render_404 render file: Rails.root.join('public/404.html').to_s, status: :not_found, layout: false, content_type: 'text/html' end def render_500(error) logger.error("エラークラス: #{error.class}") logger.error("エラーメッセージ : #{error.message}") logger.error('バックトレース -------------') logger.error(error.backtrace.("\n")) logger.error('-------------') render file: Rails.root.join('public/500.html').to_s, status: :internal_server_error, layout: false, content_type: 'text/html' end end
config.consider_all_requests_localをfalseにするだけで、development環境でエラーページの動作を確認できる
trueに設定すると、どのような種類のエラーが発生しても、詳細なデバッグ情報がHTTPレスポンスに出力される。
developmentとtest環境ではtrue、production環境ではfalseに設定されている。
(config/environments/development.rb) # Show full error reports. # falseにするだけでdevelopment環境でエラーページの動作を確認できる config.consider_all_requests_local = false
意図的にエラーを発生させる
get '*path', to: 'application#render_500' get '*path', to: 'application#render_404'
エラーログの参考資料
エラーログ
log/development.log Started GET "/boards/599" for ::1 at 2020-04-29 11:58:10 +0900 Processing by BoardsController#show as HTML Parameters: {"id"=>"599"} [1m[36mUser Load (2.5ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?[0m [["id", 43], ["LIMIT", 1]] ↳ vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98 [1m[36mBoard Load (0.2ms)[0m [1m[34mSELECT "boards".* FROM "boards" WHERE "boards"."id" = ? LIMIT ?[0m [["id", 599], ["LIMIT", 1]] ↳ app/controllers/boards_controller.rb:26 Rendering public/404.html Rendered public/404.html (4.7ms) Completed 404 Not Found in 61ms (Views: 16.7ms | ActiveRecord: 2.7ms)
log/development.log Started GET "/login" for ::1 at 2020-04-29 11:59:39 +0900 Processing by UserSessionsController#new as HTML エラークラス: NameError エラーメッセージ : undefined local variable or method `hello' for #<UserSessionsController:0x00007fd3cda92010> バックトレース ------------- Completed 500 Internal Server Error in 219ms (ActiveRecord: 0.0ms) NoMethodError (undefined method `call' for #<Array:0x00007fd3c77ebf88>): app/controllers/application_controller.rb:20:in `error500'
エラーページを作成する
Railsは標準で、public/404.htmlとpublic/422.html、public/500.htmlが作成されているが、以下のサイトなどを使って自前のエラーページを作るのもロマンがあるというか、面白味があると思う。
たった1分で素敵なエラーページが作れるサイト「Better Error Pages」 | ライフハッカー[日本版]
エラー時にslack通知する
gemのインストール。
gem 'slack-notifier' gem'exception_notification'
チャンネルの右上の「iマーク」を押す。
詳細が表示されるから、その他→アプリを追加する。
こんなページへ飛ぶ。
チャンネルのWebhookURLを取得
例外エラーをslackチャンネルに通知するよう設定
$ be rails g exception_notification:install
create config/initializers/exception_notification.rb
(config/initializers/exception_notification.rb) ExceptionNotification.configure do |config| config.add_notifier :slack, { webhook_url: Rails.application.credentials.dig(:slack, :webhook_url), channel: Settings.slack.exception_notification_channel } end
config.add_notifier :slack, webhook_url: Rails.application.credentials.slack[:webhook_url], channel: チャンネル名
settingsファイルで設定もあり
(config/settings/development.yml) slack: exception_notification_channel: '#基礎編通知'
※500番エラー(サーバー側の問題)が発生した時だけ、通知が来るようになっている
→通知が来ることで、改修などを行える
※404などの間違ったURLを入力した等のエラー(クライアント側の問題)で毎回通知が来る必要はない。
credentialsファイルに秘匿情報(チャンネルURL)を保存しておく。
$ EDITOR="vi" bin/rails credentials:edit
# credentialの中身 slack: webhook_url: 取得したURL
config/credentials.yml.enc
に、暗号化した情報が入る(リモート上で管理したくない秘匿情報)。
→そしてmaster_keyに暗号を解くための鍵が入っており、情報の暗号化、複合を行ってくれる。
また、master_keyはバージョン管理対象外となっている。
.gitignore # Ignore master key for decrypting credentials and more. /config/master.key
こんな感じでslackに通知される。
credentials:editを実行できなかった場合 →credentials.yml.encを別フォルダに退避してからrmコマンドで削除し、credentials:editを再実行したら、新しいcredentialsファイルが作成された
【Rails5.2】秘匿情報はsecret.ymlではなくcredentials.yml.encで管理する【初心者】 - Qiita
参考資料
Railsアプリの例外ハンドリングとエラーページの表示についてまとめてみた - Qiita
Rails のエラー処理について知ってる範囲でまとめ - Qiita