homeASCIIcasts

24: The Stack Trace 

(view original Railscast)

Other translations: It

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.