2009-09-23 3 views
18

Hier ist ein echtes kleines Beispiel:Ruby-Rettung Ganzbacktrace So zeigen

puts File.join(nil, "hello") 

ausgeben würde

test.rb:4:in 'join': can't convert nil into String (TypeError) 
from test.rb:4 

Aber wenn ich dies tun:

begin 
    puts File.join(nil, "hello") 
rescue => exception 
    puts exception.backtrace 
end 

Dies wird Ausgang

test.rb:4:in 'join' 
test.rb:4 

Wie erfasse ich nun die vollständige Backtrace, einschließlich der "Kann nicht Nil in String (TypeError)" Teil?

@Sarah Vessels: In meinem speziellen Code, dieser Ausschnitt:

puts "==============================" 
puts error.message 
puts "==============================" 
puts error.inspect 
puts "==============================" 
puts error.backtrace 
puts "==============================" 

kehrt

============================== 
exit 
============================== 
#<SystemExit: exit> 
============================== 
/usr/lib/ruby/1.8/glib2.rb:37:in `exit' 
/usr/lib/ruby/1.8/glib2.rb:37:in `exit_application' 
multi.rb:234:in `main' 
multi.rb:347 
============================== 
+0

Nach Ihrer Bearbeitung sieht es so aus, als ob Ihre Rettung eine SystemExit-Ausnahme (ausgelöst beim Aufruf von exit) statt des TypeError beim Versuch, nil mit einer Zeichenfolge beizutreten, abfängt. Was ist in der multi.rb Zeile 234? – mikej

Antwort

24

Der Wert irgendwo auf diesem Aufruf basiert gespeichert ist, auf #inspect:

irb(main):001:0> begin 
irb(main):002:1* puts File.join(nil, "Hello") 
irb(main):003:1> rescue => exception 
irb(main):004:1> puts exception.inspect 
irb(main):005:1> end 
#<TypeError: can't convert nil into String> 
=> nil 

Exception#message ist der beschreibende Teil:

irb(main):006:0> begin 
irb(main):007:1* puts File.join(nil, "hello") 
irb(main):008:1> rescue => ex 
irb(main):009:1> puts ex.message 
irb(main):010:1> end 
can't convert nil into String 
=> nil 

So die Art der Daten, die Sie suchen zu bekommen, Sie so etwas wie das folgende tun könnte:

irb(main):015:0> begin 
irb(main):016:1* puts File.join(nil, "hey") 
irb(main):017:1> rescue => ex 
irb(main):018:1> puts "#{ex.backtrace}: #{ex.message} (#{ex.class})" 
irb(main):019:1> end 
(irb):16:in `join'(irb):16:in `irb_binding'C:/Ruby/lib/ruby/1.8/irb/workspace.rb 
:52:in `irb_binding':0: can't convert nil into String (TypeError) 
=> nil 
+0

Ja, ich habe das versucht =/Der Code, den ich ausführe, ist eine Ruby-Gnome-Hauptschleife. Wenn sie einen Fehler erfasst, entscheidet sie, dass der Fehler von Gtk.main kommt, nicht von Zeile 234 in multi.rb. Beginne und rette Wraps um Gtk.main. – RyanScottLewis

2

@SaraVessels beantworten ist näher an, was Sie wollen , aber ich dachte, eine fertige Alternative könnte auch anderen helfen.

Für die scripties von uns kommt Rubin mit zwei praktischen Globals (na ja, faden global glaube ich), $! und [email protected], die auf die letzte Exception und letzte Ausnahmen Backtrace.

begin 
    puts File.join(nil, "Hello") 
rescue 
    puts $! # ("no implicit ....") 
    puts [email protected] # backtrace 
end 

AUSGABE:

no implicit conversion of nil into String 
/tmp/e.rb:2:in `join' 
/tmp/e.rb:2:in `<main>' 

Dies ist nicht sehr explizit, aber praktisch in interaktiven oder sehr prototypish Einstellungen.

Rubin stdlib beinhaltet das 'English' Modul (ja, Groß-), mit dem Sie

require "English" # capital-E! 
# ... 
    puts $ERROR_INFO  # $! ("no implicit ....") 
    puts $ERROR_POSITION # [email protected] backtrace 
# ... 

Sein seltsam tun konnte und ich es nie benutzt - aber vielleicht jemand ist Happ (y | ier) damit.