#24 The Stack Trace
When you’re developing a Rails application you’ll often see an error page that looks like this.
The error page showing the stack trace.
As well as the actual error message, the error page shows a stack trace. The stack trace can look a little intimidating at first, but it can provide vital information about what’s causing your app to fall over. (Note that the page above has had a lot the lines removed from its stack trace.) We’ll look through our stack trace to debug our application shortly. First, we’ll explain exactly what a stack trace is.
What is a stack trace?
To show a stack trace we’ll open irb
, Ruby’s interactive console. A stack trace is shown when an error is raised, so we’ll raise one.
>> raise "test error" RuntimeError: test error from (irb):1 >>
The stack trace here is short, just one line. Now we’ll raise an error in a method.
>> def foo >> raise "test error" >> end => nil >> foo RuntimeError: test error from (irb):3:in `foo’ from (irb):5 >>
When we call the method it appears in the stack trace. If we define another method that calls foo then we’ll see that method appear in the stack trace too.
>> def bar >> foo >> end => nil >> bar RuntimeError: test error from (irb):3:in `foo’ from (irb):7:in `bar’ from (irb):9 >>
bar
calls foo
which raises the error and you can see each method in the stack trace. The stack trace in a Rails error page works in the same way. We’ll take a look at our stack trace now and try to fix our code.
Debugging our Code
The first lines of our stack trace are below
/Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2578:in ‘attributes=’ /Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2283:in ‘initialize’ app/controllers/tasks_controller.rb:7:in ‘new’ app/controllers/tasks_controller.rb:7:in ‘show’
The first couple of lines aren’t much use to us as they show where the error occurred in the Rails framework. Our error is unlikely to be in there, though. The next two lines show the error happening in our task controller, in the new method which is called by show
. We’ll take a look at our task controller code and see if we can find it.
class TasksController < ApplicationController def index @tasks = Task.find(:all, :include => :project) end def show @task = Task.new(params[:id]) end end
Our TaskController
method, including the error in the show
method.
The error is in our show method. We should have typed Task.find instead of Task.new. We’ll make the change and reload our page.
It works! Following the stack trace has helped us fix our bug. There’s one last trick we can use to help us debug our apps. A plugin called Rails Footnotes will turn the lines from the stack trace into clickable links that will open the appropriate file in TextMate. To install it, run the following line from your app’s directory (you’ll need to have git installed on your machine).
git clone git://github.com/drnic/rails-footnotes.git vendor/plugins/footnotes rm -rf vendor/plugins/footnotes/.git
Now, you can just click a line in the stack trace and immediately see the file in TextMate which makes finding your bugs even easier.