I am feeling
The current mood of sweetperceptions at www.imood.com
right now.
Home  Email  Rss  PHP  Ruby

Meaningful 404s and 500s

 July 6th, 2008

My site is still young and contents aren't that many right now, but what I really enjoy doing is making all the pages look better and be more usable. One thing that I recently gave thought on were my error pages.

I tried to advertently access a missing page, and I was greeted with my old one liner text and a suggestion to visit my blog. At the bottom of it was my twitter feed. It had the same layout as the rest of my site's pages and had the usual links on the right side. Funny though, when you access this missing page, it did take the usual loading time only to be displayed with such a page. And so I thought it needed a revamp.

Aside from thoughts on usability, I wanted really to put some things that can't really be done from plain HTML. I wanted to put some of my recent posts as suggestions for visits. These and I get stuck with an HTML file for 404 or 500. And so, after some time of research, I found a very nice solution.

I came across a wiki entry on how to configure the error page of your application and proposed that ActionController::Rescue's rescueactionin_public will be overriden in the application.rb of your application.

Rails' 404 and 500 error pages are located in the public directory of your application and they are in plain HTML files. The only way for us to use layouts is to put it somewhere inside the application where layouts and the ActionController can do its tasks.

A 404 error can be triggered when there is a path retrieved and its not found anywhere in the application. The easiest way to catch this and point it to a controller/method. In your config/routes.rb, add the lowest priority route definition:

map.connect '*path', :controller => 'application', :action => 'rescue_404' unless ::ActionController::Base.consider_all_requests_local

When all routes have been checked and that the currently requested file is not found, it lands on the lowest priority route and makes a request to application.rb's rescue404. The rescueaction_in_public receives the call and directs to the right template. In your application.rb, put these codes:

  def rescue_404
    rescue_action_in_public(ActionController::RoutingError)
  end

  def rescue_action_in_public(exception)
    #maybe gather up some data you'd want to put in your error page

    case exception
      when ActionController::InvalidAuthenticityToken
      when ArgumentError
      when SyntaxError
        render :template => "shared/error500", :layout => "error", :status => "500"
      else
        render :template => "shared/error404", :layout => "error", :status => "404"
    end          
  end

  def local_request?
    return false
  end

This works, but these codes just catches the 404 errors, but not the 500s. I found this out the hard way, but I'm saving you time and letting you know how to work this out. By reading further, some are suggesting to put specific rescueactionin_public methods per controller. I think that this would be too tiring, and so having a DRY implementation of it would be better.

Since some errors occur before any controllers are loaded, we need to create a "pre-controller" approach. Create a pre controller in your lib folder. You can name it as you please. Put in the following lines:

class ActionController::Base

  def rescue_action_in_public(exception)
    #maybe gather up some data you'd want to put in your error page

    case exception
      when ActiveRecord::RecordNotFound
      when ActiveRecord::RecordInvalid
      when ActionController::RoutingError
      when ActionController::UnknownController
      when ActionController::UnknownAction
      when ActionController::MethodNotAllowed
        render :template => "shared/error404", :layout => "error", :status => "404"
      else
        render :template => "shared/error500", :layout => "error", :status => "500"
    end             end

end

Strap the loading of this file into your config/environment.rb like this:

require 'error_catcher'

or whatever you named your file with. After that, you now need to create your templates and layout files as necessary. Well, I'm sure you already know how to work that out. smile

That's it. I haven't found any bright alternatives, but it works for me, and I think it just needs a little cleaning and it'll be better.

5 Responses to “Meaningful 404s and 500s”

  • zeddy
     

    Thanks works a treat … this let me put the finishing touches to my site!

  • Alex
     

    I can’t seem to get this to work. I put actioncontroller in /lib/ and required it in my environment.rb and all I ever get is “uninitialized constant ActionController”

  • Alex
     

    I can’t seem to get this to work. I put actioncontroller in /lib/ and required it in my environment.rb and all I ever get is “uninitialized constant ActionController”

  • PhilT
     

    Thanks for this. Might be nice to modify this to add support for 422.

    If I do it myself I’ll post the changes :)

  • PhilT
     

    Alex, put the require at the bottom of the environment

Leave a Reply

Seriously, I like it when people give words of wisdom, or even share their own joys and/or sorrows.  Even those people who leave good thoughts and advices are alright.  Its okay.  But if you don't tell me who you are or if that I find that you picked my blog...


comments Comments »
Its a wonderful feeling that you are loved, and yes, its even better when you have someone to love.  In tagalog.. "kay sarap nang may minamahal.."  smile  Yep, its really great when everything seems perfect.. but then you get to ask yourself why on earth should you deserve this?  Is...


comments Comments »
If you haven't read Jules Verne's Journey to the Center of the Earth and weren't even able to watch the movie Journey to the Center of the Earth, then I hope you'll find it intriguing to watch the movie or buy the book after I relate our experience.I love Jules...


comments Comments »
Inspiration is nothing compared to Action itself.. I think so, I believe so..We should be taught not to wait for inspiration to start a thing. Action always generates inspiration. Inspiration seldom generates action.--Frank Tibolt [From MockObjects.com]&nb...


comments Comments »
I'm not a US citizen, in fact, I've never been there.  I'm not a politician or a political analyst/thinker.  But I do know a good person when I see one.  We all do right?  If I can vote for a US Presidency candidate, I'd pitch my vote for Barack Obama.Not...


comments Comments »
[video align='align-left']http://www.youtube.com/watch?v=rafEFSXVtuw[/video]While on the way home, as usual, I had to compete with a lot of people going to Quiapo.  I got a little pissed off because the drivers feel like once they have the "Derecho" sign boards they automatically upgrade their fare to 30 bucks!  They still pass by...


comments Comments »
I'm out of my league.  Hell, I didn't even know why I was there.  I knew I wanted to come because I wanted to try new things!  I don't really like gambling, and was quite hesitant to come, yet I wanted to learn how to play poker.  smile  My honey...


comments Comments »
Two days ago, my youngest sister was suddenly in the mood to watch Kill Bill again.  Well, since none at home had any violent reactions, we watched Volume 1 at around 8pm.  Supposedly, my honey and I were to discuss something very important that night, but then we opted to...


comments Comments »
Why are things the way they are?  When things don't work for you, but seem to work for others and you feel bad that its taking its course in other people's lives.. would you want to interfere and make their lives easier (in your perspective)?Just a thought.. &nb...


comments Comments »
After a long pause.. Hiatus from blogging, hiatus from twittering, hiatus from movie watching.. well, I'm back. As far as I can recall, the last movie I watched was Rogue. smile Its been like a month already. Well, the perfect movie to watch on a come back is one that...


comments Comments »
  • i just don't like being lied to. i can take a bitter truth but not a beautiful lie 2008-11-14
  • how could "a moment" take so long as 2 hours? especially if you say you're sleepy 2008-11-14
  • woohoo.. i'm happy for this weekend. smile 2008-11-14
  • nakiki-twitter lang kay Chris... buwahahahaha! - Deyey 2008-11-08
  • good to have the friendly internet always handy.. hehe 2008-11-08
  • its kinda boring to stay in a hotel for a day long.. sad 2008-11-08
  • i love control panels.. it keeps the end users off your shoulders.. hihi 2008-11-07
  • @gdawge yah, i wanna retire early today and take a break.. maybe tomorrow would be better.. sigh 2008-11-06