Catching line numbers in ruby exceptions
Solution 1
p e.backtrace
I ran it on an IRB session which has no source and it still gave relevant info.
=> ["(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"]
If you want a nicely parsed backtrace, the following regex might be handy:
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]
]
( Regex /should/ be safe against weird characters in function names or directories/filenames ) ( If you're wondering where foo camefrom, i made a def to grab the exception out :
>>def foo
>> thisFunctionDoesNotExist
>> rescue Exception => e
>> return e
>>end
>>x = foo
>>x.backtrace
Solution 2
You can access the backtrace from an Exception object. To see the entire backtrace:
p e.backtrace
It will contain an array of files and line numbers for the call stack. For a simple script like the one in your question, it would just contain one line.
["/Users/dan/Desktop/x.rb:4"]
If you want the line number, you can examine the first line of the backtrace, and extract the value after the colon.
p e.backtrace[0].split(":").last
Solution 3
Usually the backtrace contains a lot of lines from external gems It's much more convenient to see only lines related to the project itself
My suggestion is to filter the backtrace by the project folder name
puts e.backtrace.select { |x| x.match(/HERE-IS-YOUR-PROJECT-FOLDER-NAME/) }
And then you can parse filtered lines to extract line numbers as suggested in other answers.
Solution 4
Throwing my $0.02 in on this old thread-- here's a simple solution that maintains all the original data:
print e.backtrace.join("\n")
anshul
Updated on July 28, 2022Comments
-
anshul almost 2 years
Consider the following ruby code
test.rb:
begin puts thisFunctionDoesNotExist x = 1+1 rescue Exception => e p e end
For debugging purposes, I would like the rescue block to know that the error occurred in line 4 of this file. Is there a clean way of doing that?