2009-09-23 7 views
18

He aquí un verdadero ejemplo rápido:Rubí Rescate en pantalla completa Backtrace

puts File.join(nil, "hello") 

salida sería

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

Pero cuando hago esto:

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

Esta es la salida

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

Ahora, ¿cómo puedo capturar la traza inversa completa, incluida la parte "no se puede convertir nada en String (TypeError)"?

buques @Sarah: En mi código específico, este fragmento:

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

devuelve

============================== 
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

Después de su edición, parece que su rescate atrapa una excepción SystemExit (que se produce cuando llama a exit) en lugar de que TypeError intente unirse a nil con String. ¿Qué hay en la línea 234 de multi.rb? – mikej

Respuesta

24

el valor se almacena en alguna parte, sobre la base de este llamado a #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 es la parte descriptiva:

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 

Así que para obtener el tipo de datos que está buscando, usted podría hacer algo como lo siguiente:

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

Sí, lo he intentado =/El código que estoy ejecutando es un bucle principal de ruby-gnome así que cuando captura un error, decide que el error es de Gtk.main, no de la línea 234 en multi.rb. comenzar y rescatar se envuelve alrededor de Gtk.main. – RyanScottLewis

2

@SaraVessels respuesta es más cerca de lo que quiere , pero pensé que una alternativa lista para usar también podría ayudar a otros.

Para los scripties de nosotros, rubí viene con dos variables globales a mano (bueno, hilo global creo), y $![email protected] que apuntan a la última Excepción y la última traza excepciones.

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

la Salida:

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

Esto no es muy explícita, pero es práctico en los entornos interactivos o muy prototypish.

Rubí stdlib incluye el módulo de 'English' (sí, en mayúsculas), con la que se podría hacer

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

Su extraña y nunca lo usó - pero tal vez alguien está Happ (y | IER) con eso.