Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Handle only 404s dynamically. It uses a normal controller and route for 404s, letting everything else go to the Rails default /public error pages. In my case it was to use the subdomain logic in my ApplicationController.
module MyApp
class Application < Rails::Application
require Rails.root + 'lib/custom_public_exceptions'
config.exceptions_app = CustomPublicExceptions.new Rails.public_path
end
end
class CustomPublicExceptions < ActionDispatch::PublicExceptions
def call(env)
status = env["PATH_INFO"][1..-1]
if "404" == status
# handle just 404 in our routes
MyApp::Application.routes.call env
else
super env
end
end
end
class ErrorsController < ApplicationController
skip_before_filter :authenticate_user! # if using Devise
def not_found
end
end
Geknowm::Application.routes.draw do
match "/404", :to => "errors#not_found"
end
@henrik

This comment has been minimized.

Copy link

commented Aug 8, 2014

Thanks for this. In Rails 4 you need

match "/404" => "errors#not_found", via: [ :get, :post, :patch, :delete ]

And in case someone misses it, "MyApp" above should be whatever module you define in config/application.rb.

You may need to remove public/404.html so it doesn't appear of your custom action.

To see the page in dev, just visit /404. Or change config/environments/development.rb to say

config.consider_all_requests_local = false

but make sure you don't keep it. For one thing, it makes for a lot less helpful errors in dev.

@henrik

This comment has been minimized.

Copy link

commented Aug 8, 2014

Wrote up my modifications as a blog post: http://thepugautomatic.com/2014/08/custom-404-page-with-rails-4/

@codeanpeace

This comment has been minimized.

Copy link

commented Jan 27, 2015

@henrik Was that intentional? xD

@mdeering

This comment has been minimized.

Copy link

commented Feb 13, 2015

@henrick I hope that link to a nginx 404 was in fact intentional got a good chuckle from that.

@dhulihan

This comment has been minimized.

Copy link

commented Mar 27, 2015

@tomprats

This comment has been minimized.

Copy link

commented Nov 5, 2015

Pretty great, one simple change is to use Rails.application.routes.call env instead of MyApp::Application.routes.call env so that you don't have to change that line to your application

@tannguyen

This comment has been minimized.

Copy link

commented Mar 17, 2016

class CustomPublicExceptions < ActionDispatch::PublicExceptions

  def call(env)
    status      = env["PATH_INFO"][1..-1]

    if "404" == status
      # handle just 404 in our routes
      MyApp::Application.routes.call env
    else
      super env
    end
  end

end

Can you write spec for this?

@SunDi3yansyah

This comment has been minimized.

Copy link

commented Sep 19, 2016

how, if I want to call the page can not be found on another controller to provide the conditions?

if no_session.nil?
  # how to call 404 page
  return false
else
  return true
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.