Поймать номера строк в исключениях ruby - PullRequest
45 голосов
/ 23 сентября 2008

Рассмотрим следующий код рубина

test.rb:

begin

  puts
  thisFunctionDoesNotExist
  x = 1+1
rescue Exception => e
  p e
end

В целях отладки я хотел бы, чтобы блок спасения знал, что ошибка произошла в строке 4 этого файла. Есть ли чистый способ сделать это?

Ответы [ 5 ]

69 голосов
/ 23 сентября 2008
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]
]

(Regex / должен быть / безопасен от странных символов в именах функций или каталогах / именах файлов) (Если вам интересно, откуда взялся foo, я попытался исключить исключение:

>>def foo
>>  thisFunctionDoesNotExist
>> rescue Exception => e 
>>   return e 
>>end     
>>x = foo 
>>x.backtrace
20 голосов
/ 23 сентября 2008

Вы можете получить доступ к обратному следу из объекта Exception. Чтобы увидеть весь след:

p e.backtrace

Он будет содержать массив файлов и номеров строк для стека вызовов. Для простого скрипта, подобного написанному в вашем вопросе, он будет содержать только одну строку.

["/Users/dan/Desktop/x.rb:4"]

Если вам нужен номер строки, вы можете просмотреть первую строку обратной трассировки и извлечь значение после двоеточия.

p e.backtrace[0].split(":").last
6 голосов
/ 06 марта 2015

Обычно обратная трассировка содержит много строк из внешних драгоценных камней. Гораздо удобнее видеть только строки, связанные с самим проектом

Мое предложение состоит в том, чтобы отфильтровать обратную трассировку по имени папки проекта

puts e.backtrace.select { |x| x.match(/HERE-IS-YOUR-PROJECT-FOLDER-NAME/) }

И затем вы можете анализировать отфильтрованные строки, чтобы извлечь номера строк, как это предлагается в других ответах.

6 голосов
/ 25 июня 2010

Добавление моих $ 0,02 в эту старую ветку - вот простое решение, которое поддерживает все исходные данные:

print e.backtrace.join("\n")
0 голосов
/ 21 мая 2010

Возможно, что в Ruby 1.9.3 вы сможете получить доступ не только к этой информации более структурированным, надежным и простым способом без использования регулярных выражений для вырезания строк.

Основная идея состоит в том, чтобы ввести объект фрейма вызова, который предоставляет доступ к информации о стеке вызовов.

См. http://wiki.github.com/rocky/rb-threadframe/,, который, увы, требует исправления Ruby 1.9. В RubyKaigi 2010 (конец августа 2010 г.) запланировано собрание, посвященное внедрению объекта Ruby в Ruby.

Учитывая это, самое раннее, что могло произойти, это Ruby 1.9.3.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...