Przechwytywanie numerów linii w wyjątkach ruby
Rozważ następujący kod ruby
Test.rb:
begin
puts
thisFunctionDoesNotExist
x = 1+1
rescue Exception => e
p e
end
Do celów debugowania, chciałbym, aby blok rescue wiedział, że błąd wystąpił w linii 4 tego pliku. Jest na to jakiś czysty sposób?
5 answers
p e.backtrace
Uruchomiłem go na sesji IRB, która nie ma źródła i nadal daje istotne informacje.
=> ["(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"]
Jeśli chcesz dobrze przetworzyć backtrace, następujące wyrażenia regularne mogą być przydatne:
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 / powinien / być bezpieczny przed dziwnymi znakami w nazwach funkcji lub katalogach/nazwach plików ) ( Jeśli zastanawiasz się, gdzie pojawił się foo, zrobiłem def, aby pobrać wyjątek:
>>def foo
>> thisFunctionDoesNotExist
>> rescue Exception => e
>> return e
>>end
>>x = foo
>>x.backtrace
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 06:01:59
Możesz uzyskać dostęp do backtrace z obiektu Exception. Aby zobaczyć cały backtrace:
p e.backtrace
Będzie zawierać tablicę plików i numerów linii stosu wywołań. Dla prostego skryptu, takiego jak ten w twoim pytaniu, zawierałby tylko jedną linię.
["/Users/dan/Desktop/x.rb:4"]
Jeśli chcesz podać numer linii, możesz sprawdzić pierwszy wiersz ścieżki i wyodrębnić wartość za dwukropkiem.
p e.backtrace[0].split(":").last
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 05:50:30
Wrzucenie mojego $0.02 w ten stary wątek-- oto proste rozwiązanie, które zachowuje wszystkie oryginalne DANE:
print e.backtrace.join("\n")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-24 23:54:20
Zazwyczaj backtrace zawiera wiele linii z zewnętrznych klejnotów O wiele wygodniej jest zobaczyć tylko linie związane z samym projektem
Moją propozycją jest filtrowanie backtrace według nazwy folderu projektu
puts e.backtrace.select { |x| x.match(/HERE-IS-YOUR-PROJECT-FOLDER-NAME/) }
A następnie możesz parsować przefiltrowane linie, aby wyodrębnić numery linii zgodnie z sugestiami w innych odpowiedziach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-06 11:26:10
Jest możliwe, że w Ruby 1.9.3 będziesz mógł uzyskać dostęp nie tylko do tych informacji w bardziej ustrukturyzowany, niezawodny i prostszy sposób bez użycia wyrażeń regularnych do cięcia łańcuchów.
Podstawową ideą jest wprowadzenie obiektu ramki wywołań, który daje dostęp do informacji o stosie wywołań.
Zobacz http://wiki.github.com/rocky/rb-threadframe / , który niestety wymaga łatania Rubiego 1.9. W RubyKaigi 2010 (koniec sierpnia 2010) planowane jest spotkanie omówienie wprowadzenia obiektu ramki do Rubiego.
Biorąc to pod uwagę, najwcześniej może się to zdarzyć w Ruby 1.9.3.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-21 09:08:46