Clickable Stack Traces on your Rails Error Page
Wouldn’t it be nice if when an error happened in your application, you could not only see the stack trace, but click on a line and jump to the offending code? This is not groundbreaking stuff, I know, I had this like 10 years ago in C++ and later Java fat clients, and I’m sure other languages & IDEs had it too – but somehow in moving to writing web apps in Ruby, I lost it.
I want it back damnit!
Turns out it’s pretty easy to get back (at least it is if you use textmate) – check it out.
Custom Error Page
First, to get a custom error page for your project, add something like this to your application.rb :
def rescue_action_locally(*args) render :template => "application/public_error", :layout => false end alias rescue_action_in_public render_action_locally
Note, if you’re using exception notifiable, you probably want to change the last line to something like :
alias render_404 rescue_action_locally alias render_500 rescue_action_locally
We use markaby, so our public_error template looks something like this; it’s probably a good idea to keep this simple and not use a layout, just in case the error came from the layout :
html do head do title action_name stylesheet_link_tag 'error' end body do div.error do div.message do h1 "Whoops" p "We detected an error. Don't worry, though, we've been notified and we're on it." end end end end
Adding a Stack Trace w/ Links to the Error Page
So, it would be helpful to us for our error page to tell us more in our development and staging environments. We do use exception notifiable, so we don’t actually need or want it to say anything else to a real user in production. Adding this to our template, it now looks like this :
html do head do title action_name stylesheet_link_tag 'error' end body do div.error do div.message do h1 "Whoops" p "We detected an error. Don't worry, though, we've been notified and we're on it." end if RAILS_ENV != 'production' div.stack_trace do h2 "Stack Trace" div { link_to_code $!.to_s.to_s.gsub("\n", " ") } hr div { link_to_code $!.backtrace.join(" ") } end end end end end
What’s that “link_to_code” method in there?
It’s a method in application_helper that replaces any path with a textmate url to open up that file on your local system and jump to the offending line. Check it out :
def link_to_code(text) text.gsub(/([\w\.-]*\/[\w\/\.-]+)\:(\d+)/) do |match| file = $1.starts_with?("/") ? $1 : File.join(RAILS_ROOT, $1) link_to match, "txmt://open?url=file://#{file}&line=#{$2}" end end
That’s it. Suddenly, stack traces are friendly again!
April 30th, 2008 at 6:29 pm
Great post Jeremy,
How are things going?
I am keen to explore rails and ruby at some point soon.
I am going to be looking to this blog for guidance as I know the quality of the author and the material.
Hope all is well. Congrats on your wedding.
And I will hopefully bump into you sometime in the near future.
All the best.
JR