Railsでエラーページを表示する.

いつもpublic/404.htmlとか編集してる程度だったので、Railsの仕組みを使ったエラーページを作ろうかと色々試行錯誤してみた.


因にエラーページは通常はProductionモードでHTTPアクセスをローカルホスト( localhost / 127.0.0.1 )以外でアクセスしたときに確認できます.

エラーページの実装方法

方法はググってみると、ざっと3種類あった.

  • public/404.htmlを書き換える
  • ApplicationController内でrescue_fromを追記
  • ApplicationController内でrescue_action_in_publicメソッドをオーバライド


色々やるなら、最後のrescue_action_in_publicオーバライドする方法が一番よさそう. ただ欲を言うとRails自身もProductionモードのときちゃんと、404.htmlとか表示してるからその機能っぽくしたい.

Railsのコードを読んでみた.

ActionController::RescueにDEFAULT_RESCUE_RESPONSESなんてモノがあるじゃないか!コレを使ってRailsは例外からHTTPステータスコードに変換して404.htmlを表示してた.

    DEFAULT_RESCUE_RESPONSES = {
      'ActionController::RoutingError'             => :not_found,
      'ActionController::UnknownAction'            => :not_found,
      'ActiveRecord::RecordNotFound'               => :not_found,
      'ActiveRecord::StaleObjectError'             => :conflict,
      'ActiveRecord::RecordInvalid'                => :unprocessable_entity,
      'ActiveRecord::RecordNotSaved'               => :unprocessable_entity,
      'ActionController::MethodNotAllowed'         => :method_not_allowed,
      'ActionController::NotImplemented'           => :not_implemented,
      'ActionController::InvalidAuthenticityToken' => :unprocessable_entity
    }


ステータスコード自体はActionController::StatusCodes::STATUS_CODESで管理してた.

    STATUS_CODES = {
      :
      :
      200 => "OK",
      :
      404 => "Not Found",
      :
      500 => "Internal Server Error",
      :
      :
    }

例外毎にHTTPステータスを割り当てて表示する方法.

Railsのコードを読んで大体なにしてるか分かったので、404.htmlの用に例外からステータスコードを判定して表示するコードを書いてみた.


renderでレイアウトとか色々してるけどこの辺は普通のコントローラと書き方は同じ.

class ApplicationController < ActionController::Base

  # 例外とステータスの関連付け
  rescue_responses.update({
    'Foo::BarError' => :not_found
  })

  protected

    # 確認をhttp://localhost 等で確認するときはコメントアウト
    # が定石
    #def local_request?
    #  false
    #end
  
    def rescue_action_in_public(exception) #:doc:
      status_message_sym = response_code_for_rescue(exception) || :internal_server_error
      @http_status_code = SYMBOL_TO_STATUS_CODE[status_message_sym]
      
      respond_to do |format|
        format.html { render :template => "commons/error.html", :layout => 'application', :status => @http_status_code }
      end
    end


end

テンプレートをRAILS_ROOT/views/commons/error.html.erbに作成して、Productionモードで確認.

<%
title = "#{@http_status_code} #{ActionController::StatusCodes::STATUS_CODES[@http_status_code]}"
-%>
<h1><%= title %></h1>

<p>
<% if @http_status_code == 403 # Forbidden -%>
アクセス権限がありません.
<% elsif @http_status_code == 404 # Not Found -%>
お探しのページが見つかりませんでした.
<% elsif @http_status_code == 422 # Unprocessable Entity -%>
指定されたエンティティの処理ができませんでした.
<% elsif @http_status_code == 500 # Internal Server Error -%>
システムに障害が発生しました.
<% end -%>
</p>
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy