I launched JCFootballProspects.com a while ago and things have been going smoothly but the site is stuck with the nasty black-on-white error messages when somebody types in a wrong address.
I’m now at the point where I want to give out some fancy 404 pages and I’ve been looking around at what other folks have done. I’m amazed to find that all the examples I can find have a 404.html page in the `#{RAILS_ROOT}/public` directory. I’m sure it’s effective to just have a plain-html file that gets served up for errors (and it’s certainly a lot better than the default ugly stuff) but I’m convinced there are advantages to having application-provided 404 pages as well.
There are three different kinds of errors I trap and respond to: * A user gives incorrect or insufficient parameters to a page view * A user attempts to access an action that doesn’t exist * A user attempts to access a controller that doesn’t exist
The first is easily handled – even the AWDWR book shows in an early example that you can output a flash message if something goes wrong with a request. The second is only slightly more complicated but, luckily, Ruby has a great way to respond to missing actions on controllers using method_missing. The solution to the third is provided by Rails’ routing capabilities.
How to hook up an app-driven 404 page: ==== The first thing I did was added a view to my default controller (mine is called ‘home’). I created ./app/views/home/404.rhtml and put just some basic stuff in it:<%= content_tag 'h2', 'Whoops!' %>
<%= content_tag 'h3', 'Page not found' %>
[insert message here]
The next step was to add method_missing to my application controller:
1 2 3 4 5 6 7 8 9 10 11 |
class ApplicationController < ActionController::Base ... def method_missing(methodname, *args) @methodname = methodname @args = args render 'home/404', :status => 404 end end |
map.error ':controllername', :controller => 'home',
:action => '404'
10 responses so far ↓
1 sasha // Aug 12, 2006 at 04:48 PM
def rescue_action_in_public(exception) # do something based on exception message = exception.backtrace.join("\n") unless exception render :file => "#{RAILS_ROOT}/public/404.html", :layout => false, :status => 404 end def local_request? false endthanks for the CSV tip. doc is atrocious2 Danger // Aug 13, 2006 at 04:33 AM
3 Ben // Feb 23, 2007 at 02:09 PM
4 Danger // Feb 23, 2007 at 04:09 PM
5 Chris // Nov 28, 2007 at 07:38 AM
The problem with using a route like “map.error ’:controllername’” is that it won’t catch ‘mysite.com/jibberish/morejibberish’. For a brickwall catch-all route, you’re best off using a wildcard route: “map.error ‘*url’ :controller => ‘home’ :action => ‘404’”
6 Anthony // Mar 11, 2008 at 11:33 AM
sorry, i don’t think i quite get this. So basically, i did the changes to my application controller and added the view, modified the routes, but when i type in some rndom non-existing url, i get an error telling me that
‘You called render with invalid options : application/404’
(in my case, i don’t use “home”, but application)
ny idea what exactly this means?
A
7 Jack Danger // Mar 11, 2008 at 05:54 PM
Anthony: Try “render :template => ‘application/404’”
This article badly needs to be updated.
8 Tony Mcintyre // Jun 14, 2008 at 03:20 AM
teraglin nizam rendlewood reorient unenraged phonautographically reservery sulphocarbamic Plymouth Creek Christian Church http://www.mnpro.com/
9 sweetperceptions // Jul 05, 2008 at 08:25 PM
What about custom 500 pages? it surely won’t be caught by the low priority route entry.. what are your thoughts?
10 sweetperceptions // Jul 06, 2008 at 01:44 AM
I just found out how to catch the 500 error messages. You can read it here: http://coderkitty.sweetperceptions.com/2008/7/6/meaningful-404s-and-500s
Leave a Comment