Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Does One Implement Dynamic 404, 500, etc Error Pages in Rails?

How does one implement dynamic, custom error pages in Rails?

For example a custom 404 error page using your application.html.erb layout and some dynamic fields in the page.

Also, how does one test this from a local machine?

like image 858
Laz Avatar asked Jun 03 '09 05:06

Laz


2 Answers

I looked at a few blog posts on Google on how to do this, unfortunately most seem to rely on polluting your ApplicationController.

What I did instead was to create a template with the 404 message then use that template to update the public/404.html file from a rake task:

# Rake file to generate static 404 page

file "public/404.html" => ["app/views/layouts/application.html.erb"] do |t|
    print "Updating 404 page\n"
    `curl --silent http://locahost/content/error404 -o public/404.html`
end 

Now whenever I update my global layout the 404 page gets updated automatically.

like image 97
Tony Edgecombe Avatar answered Nov 04 '22 05:11

Tony Edgecombe


just add the following to your ApplicationController:

  rescue_from ActiveRecord::RecordNotFound, :with => :render_record_not_found

  # Catch record not found for Active Record
  def render_record_not_found
    render :template => "shared/catchmissingpage", :layout => false, :status => 404
  end

  # Catches any missing methods and calls the general render_missing_page method
  def method_missing(*args)
    render_missing_page # calls my common 404 rendering method
  end

  # General method to render a 404
  def render_missing_page
    render :template => "shared/catchmissingpage", :layout => false, :status => 404
  end

You can customize the render call (use your templates, use a layout etc.) and catch errors this way. Now it catches missing method and record_not_found for you, but maybe there are cases where you want to display a 500 Error page so you can just go ahead, use this approach and make it fit for you.

For testing from a local machine, it just works like that. if you only want it to work in production mode, add a

 if ENV['RAILS_ENV'] == 'production'

and you're fine.

like image 27
Ole Spaarmann Avatar answered Nov 04 '22 07:11

Ole Spaarmann