Written August 8, 2014. Tagged Ruby on Rails.
This is what I did to get a custom 404 error page on Rails 4, without replacing the default 500 and 422 error pages.
There are other solutions where you just use the router as the exceptions app, but then you have to handle those other errors as well.
It's very much based on this Gist by Turadg Aleahmad, but with some cleanup and fixes.
Remove the default
public/404.html to avoid any collisions.
Modify these files like so:
class Application < Rails::Application
config.exceptions_app = CustomPublicExceptions.new(Rails.public_path)
match "/404" => "errors#error404", via: [ :get, :post, :patch, :delete ]
Add these files:
class CustomPublicExceptions < ActionDispatch::PublicExceptions
status = env["PATH_INFO"][1..-1]
if status == "404"
class ErrorsController < ApplicationController
render status: :not_found
<p>Sorry! No such page!</p>
To see the page in development, just visit
If you see the default Rails 404 page, you probably forgot to remove
If you want to make sure it actually works, change
config/environments/development.rb to say
# Do not commit!
config.consider_all_requests_local = false
Just don't keep that value, since you'll get less helpful errors in development, and you'll also disable the
/rails/info/properties page with debug info.
I haven't been able to figure out a way to do production-style error handling in a single test, so I settled for this:
describe "404 page" do
it "is customized" do
# Haven't been able to get the "show instead of exceptions" thing working in tests, but this at least makes sure the page can render correctly.
expect(page.status_code).to eq 404