Rails Diary

プログラミングの学習記録です。

例外ハンドリング

github.com

エラーは基本的にRailsが勝手にやってくれる

Railsが自動的に作ってくれたエラーページはpublicディレクトリの中にあり、Railsのデフォルトの例外ハンドリングでは、例外の種類に関わらず500 Server Errorを表示するらしい。

開発環境でやっていると赤を基調としたエラー画面のイメージしかなかったけれど、本番環境では下記のようなエラーページが表示される。(本番環境のエラーを確認する方法は後述)

400番台(処理失敗)

404 (File)Not Found

リクエストしたアドレスのページ(ファイル)が見つからない、またはそのサーバが落ちている状態。

https://i.gyazo.com/210d97ee5a708eef526daade59d4a326.png

探していたページが存在しません。 アドレスを間違って入力したか、ページが移動した可能性があります。

■ 422.html

https://i.gyazo.com/1c11d0ee8e9e0417dd59f4258d7611db.png

必要な変更は拒否されました。 アクセスできないものを変更しようとしたのかもしれません。

500番台(サーバーエラー)

サーバー側がリクエストの処理に失敗した場合。

https://i.gyazo.com/62889c4b3e2fb8ce40def37de4f2e3cc.png

申し訳ございません。不具合が発生しました。

本番と同じエラー画面を確認する方法

★ 開発環境の設定ファイルをいじる
# config/environments/development.rb
Rails.application.configure do
# 中略
  # Show full error reports.
  config.consider_all_requests.local = true # ここを

  # falseに変更するだけ
  config.consider_all_requests.local = false
  1. show full error reports(完全なエラーレポートを表示する)の設定部分をfalseに変更する
  2. 変更後は必ずサーバーを再起動させる(設定の変更をサーバー側が検知してくれるわけではないので再起動して変更を反映させる)
  3. エラー画面の確認ができたら、falseに変更した箇所をtrueに戻しておく

Railsで用意されている以外にエラーページを作る

① public配下に手動でファイルを作成する

元々あるエラーページのファイルを参考に文言を変えたてみたりレイアウトを考えればいい。

② エラーの表示させ方については下記二通りを試した

↓↓↓↓

HTTPステータスに割り当てる例外を設定する

3.9.18 config.action_dispatch.rescue_responses | Railsガイド

例外とステータスの様々なペアを指定したハッシュを一つ指定ができる。デフォルトで設定されているものは上記のリンク参照。設定されていない例外は全て500 Internel Server Errorに割り当てられる。

# config/application.rb
class Application < Rails::Application
# 中略
  config.action_dispatch.rescue_responses["Pundit::NotAuthorizedError"] = :forbidden

  # シンボルではなく数値でステータスコードを書いても動いた 
  config.action_dispatch.rescue_responses["Pundit::NotAuthorizedError"] = 403

今回はPunditを用いて権限管理をし、権限を持たないユーザーがページにアクセスした際に403.html(自作する)を表示させたかったので、Pundit::NotAuthorizedErrorエラー名と、HTTPステータス403のシンボル:forbiddenを記載しています。

rescue_fromを使ってエラーをキャッチ

rescue_from | Railsガイド

最初はこの方法を使ったやり方しか調べて辿り着けなかったのですが、こちらも特に問題なく動きます。

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  include Pundit
  
  protect_from_forgery with: :exception

  rescue_from Pundit::NotAuthorizedError, with: :render_403

  private

  def render_403
    render plain: "権限がありません(^^^^)", status: 403
  end
end
権限のないページへアクセス

↑指定した平文が表示されている

参考にしたサイト

14 rescue | Railsガイド

404ってどういう意味?HTTPステータスコードを理解しよう | SiTest (サイテスト) ブログ

本番と同じエラー画面を出したい【Rails】 - 箱のプログラミング日記。

[Rails]404/500などのエラーページって結局どうすればいいの? - CPX

[Rails]gem Punditによる権限管理 (認可)

Punditを使って権限を管理する - Qiita

Punditをなるべくやさしく解説する - Qiita