Skip to content

Instantly share code, notes, and snippets.

@gonzedge
Created January 5, 2012 02:34
Show Gist options
  • Save gonzedge/1563416 to your computer and use it in GitHub Desktop.
Save gonzedge/1563416 to your computer and use it in GitHub Desktop.
Rails 3.1 - Adding custom 404 and 500 error pages
class ApplicationController < ActionController::Base
# ...
unless Rails.application.config.consider_all_requests_local
rescue_from Exception, with: lambda { |exception| render_error 500, exception }
rescue_from ActionController::RoutingError, ActionController::UnknownController, ::AbstractController::ActionNotFound, ActiveRecord::RecordNotFound, with: lambda { |exception| render_error 404, exception }
end
private
def render_error(status, exception)
respond_to do |format|
format.html { render template: "errors/error_#{status}", layout: 'layouts/application', status: status }
format.all { render nothing: true, status: status }
end
end
# ...
end
%h2 404
%div
%h3 We're sorry
%p
The content that you requested could not be found.
%p
You tried to access '#{@not_found_path}', which is not a valid page.
%p
Want to
%a{href: root_path} go back to our home page
and try again?
class ErrorsController < ApplicationController
def error_404
@not_found_path = params[:not_found]
end
def error_500
end
end
rails generate controller errors error_404 error_500
get "errors/error_404"
get "errors/error_500"
unless Rails.application.config.consider_all_requests_local
match '*not_found', to: 'errors#error_404'
end
@karellm
Copy link

karellm commented Jan 16, 2012

I think the application_controller.rb should declare the error methods as follow:

def render_404(exception)
def render_500(exception)

instead of:

def render_404(error)
def render_500(error)

@gonzedge
Copy link
Author

Thanks @karellm for the correction!

@rgalite
Copy link

rgalite commented Apr 2, 2012

How do you make sure the exception is logged in the log/RAILS_ENV.log file?

@gonzedge
Copy link
Author

gonzedge commented Apr 5, 2012

@RudthMael, I think that adding the something like this at the top of the render_404 and render_500 should do it:

def render_404(exception)
  logger.info "Not Found: '#{request.fullpath}'.\n#{exception.class} error was raised for path .\n#{exception.message}"
  # ...
end
def render_500(exception)
  logger.info "System Error: Tried to access '#{request.fullpath}'.\n#{exception.class} error was raised for path .\n#{exception.message}"
  # ...
end

Hope this helps

@rgalite
Copy link

rgalite commented May 6, 2012

Yup. Thanks.

@pmq20
Copy link

pmq20 commented Jun 30, 2012

good. thanks

@cihad
Copy link

cihad commented Nov 13, 2012

This is hard way. for flexible exception handling read this: http://blog.plataformatec.com.br/2012/01/my-five-favorite-hidden-features-in-rails-3-2/

@dreammaker
Copy link

This is missing in the controller:

class ErrorsController < ApplicationController
  def error_404
    render status: 404
  end

  def error_500
    render status: 500
  end
end

Otherwise you'll return 200's. An alternative is to make #render_error protected and call it with the appropriate status.

This is indeed a lot of boilerplate just to use haml for my 404 page.

@dirtyhenry
Copy link

If there a good reason why you don't create a route for the errors controller actions? (useful for testing) and then redirect_to these routes from the app controller?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment