考虑以下ruby代码
test.rb:
begin
puts
thisFunctionDoesNotExist
x = 1+1
rescue Exception => e
p e
end
出于调试目的,我希望救援块知道该文件的第4行发生了错误。这样做有干净的方法吗?
答案 0 :(得分:69)
p e.backtrace
我在一个没有来源的IRB会话上运行它,它仍然提供相关信息。
=> ["(irb):11:in `foo'",
"(irb):17:in `irb_binding'",
"/usr/lib64/ruby/1.8/irb/workspace.rb:52:in `irb_binding'",
"/usr/lib64/ruby/1.8/irb/workspace.rb:52"]
如果你想要一个很好的解析回溯,下面的正则表达式可能很方便:
p x.backtrace.map{ |x|
x.match(/^(.+?):(\d+)(|:in `(.+)')$/);
[$1,$2,$4]
}
[
["(irb)", "11", "foo"],
["(irb)", "48", "irb_binding"],
["/usr/lib64/ruby/1.8/irb/workspace.rb", "52", "irb_binding"],
["/usr/lib64/ruby/1.8/irb/workspace.rb", "52", nil]
]
(正则表达式/应该/安全地防止函数名称或目录/文件名中的奇怪字符) (如果你想知道foo来自哪里,我做了一个def来抓住异常:
>>def foo
>> thisFunctionDoesNotExist
>> rescue Exception => e
>> return e
>>end
>>x = foo
>>x.backtrace
答案 1 :(得分:20)
您可以从Exception对象访问回溯。要查看整个回溯:
p e.backtrace
它将包含调用堆栈的文件和行号数组。对于像你问题中那样的简单脚本,它只包含一行。
["/Users/dan/Desktop/x.rb:4"]
如果你想要行号,你可以检查回溯的第一行,并在冒号后提取值。
p e.backtrace[0].split(":").last
答案 2 :(得分:6)
在这个旧线程上投入0.02美元 - 这是一个维护所有原始数据的简单解决方案:
print e.backtrace.join("\n")
答案 3 :(得分:6)
通常,回溯包含来自外部宝石的许多行 只查看与项目本身相关的行
更方便我的建议是按项目文件夹名称
过滤回溯puts e.backtrace.select { |x| x.match(/HERE-IS-YOUR-PROJECT-FOLDER-NAME/) }
然后您可以解析过滤后的行,以提取其他答案中建议的行号。
答案 4 :(得分:0)
有可能在Ruby 1.9.3中,您不仅可以以更结构化,更可靠,更简单的方式访问此信息,而无需使用正则表达式来剪切字符串。
基本思想是引入一个调用框架对象,该对象可以访问有关调用堆栈的信息。
请参阅http://wiki.github.com/rocky/rb-threadframe/,唉,需要修补Ruby 1.9。在RubyKaigi 2010(2010年8月下旬)中,会议计划讨论将框架对象引入Ruby。
鉴于此,最早可能发生在Ruby 1.9.3中。