程序运行中难免遇到异常,当系统抛出异常后,Rails会显示如下的一个页面。在开发过程中你经常会看到。
显示异常信息的页面。
这个页面中列出错误信息及异常堆栈。第一眼看过去可能有点晕,不过这些信息会为你定位问题提供很大的帮助(页面比较长,截图是其中的一部分)。在具体分析眼前这个错误之前,先介绍一下什么是异常堆栈。
在irb中,我们抛出一个异常。Ruby框架会根据异常出现的位置显示异常堆栈:
>> raise "test error" RuntimeError: test error from (irb):1 >>
>> def foo >> raise "test error" >> end => nil >> foo RuntimeError: test error from (irb):3:in `foo’ from (irb):5 >>
>> def bar >> foo >> end => nil >> bar RuntimeError: test error from (irb):3:in `foo’ from (irb):7:in `bar’ from (irb):9 >>
bar
方法调用foo
方法,其中在foo
方法中产生了异常。显示的异常堆栈里,越靠近异常的方法,越靠上方。了解了异常堆栈,回到最初的那个实际问题上。
异常堆栈的最前面几行为
/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’
最上面几行显示说错误发生在Rails框架内部,虽然确实如此,但往往框架内部出错的原因是由于我们的外部误用造成的。在我们的代码中找找原因,继续往下看便是我们的代码。TaskController
类中的show
方法我们本想从数据库中查询出任务对象,却使用了Task.new
方法。
class TasksController < ApplicationController def index @tasks = Task.find(:all, :include => :project) end def show @task = Task.new(params[:id]) end end
TaskController
类代码,其中show
方法中包含错误。
将Task.new
改为Task.find
之后,重新加载页面看看是不是对了。
恩,在异常堆栈的指引下,我们找到了问题所在。如果你正在使用TextMate这里再附赠一个调试中可以使用的小窍门。一个名叫Rails Footnotes的插件可以将异常堆栈中显示的行变成链接,点击链接就可以直接打开对应的文件。可以在Rails应用的根目录执行下面的命令安装。(依赖git软件)。
git clone git://github.com/drnic/rails-footnotes.git vendor/plugins/footnotes rm -rf vendor/plugins/footnotes/.git
作者授权:Your welcome to post the translated text on your blog as well if the episode is free(not Pro). I just ask that you post a link back to the original episode on railscasts.com.
原文链接:http://railscasts.com/episodes/24-the-stack-trace