Custom Error Pages

Add Custom Error Pages to your Rails App
Icons/chart bar
Used 30 times
Created by
A Alemaño

Usage
Don't let error pages break your brand's flow. Create custom error pages in Rails that match your design, keeping the user experience.

For further information: https://www.dotruby.com/articles/how-to-create-a-custom-error-page-in-rails

Run this command in your Rails app directory in the terminal:

rails app:template LOCATION="https://railsbytes.com/script/VQLs5w"
Template Source

Review the code before running this template on your machine.

run "rm public/*.html"

generate(:controller, "Errors")

create_file "app/controllers/errors_controller.rb", <<~CODE
  class ErrorsController < ApplicationController
    VALID_STATUS_CODES = %w[400 404 406 422 500].freeze

    def show
      status_code = VALID_STATUS_CODES.include?(params[:code]) ? params[:code] : 500
      respond_to do |format|
        format.html { render status: status_code }
        format.any { head status_code }
      end
    end
  end
CODE

create_file "app/views/errors/show.html.erb", <<~CODE
  <h1><%= response.code %></h1>
  <p>
    <% case response.code.to_i %>
    <% when 400 %>
      Bad Request.
    <% when 404 %>
      Not Found.
    <% when 406 %>
      Not Acceptable.
    <% when 422 %>
      Unprocessable Entity.
    <% when 500 %>
      Internal Server Error.
    <% else %>
      An unexpected error occurred.
    <% end %>
  </p>
  <%= link_to "Go back home", root_path %>
CODE

inject_into_file "config/routes.rb", after: "Rails.application.routes.draw do\n" do
  <<-CODE

  # Error handling routes
  match "/:code",
    to: "errors#show",
    via: :all,
    constraints: {
      code: Regexp.new(
        ErrorsController::VALID_STATUS_CODES.join("|")
      )
    }

  CODE
end

inject_into_file "config/application.rb", before: /^  end\nend/ do
  <<-CODE

    # Use the routes to handle exceptions
    config.exceptions_app = routes
  CODE
end

create_file "test/controllers/errors_controller_test.rb", <<~CODE
  require "test_helper"

  class ErrorsControllerTest < ActionDispatch::IntegrationTest
    VALID_STATUS_CODES = ErrorsController::VALID_STATUS_CODES

    VALID_STATUS_CODES.each do |status_code|
      test "should render \#{status_code} page" do
        get "/\#{status_code}"
        assert_response status_code.to_i
        assert_select "h1", status_code
      end
    end

    test "should return status code for non-html formats" do
      get "/404", as: :json
      assert_response :not_found
    end
  end
CODE
Comments

Sign up or Login to leave a comment.