Подтвердить что ты не робот

Ruby Rescue для отображения полной обратной трассы

Вот реальный быстрый пример:

puts File.join(nil, "hello")

Выведет

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

Но когда я это делаю:

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

Это приведет к выводу

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

Теперь, как я могу захватить полную обратную трассировку, в том числе "не могу преобразовать nil в часть String (TypeError)"?

@Суда Сары: В моем конкретном коде этот фрагмент:

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

возвращает

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

Ответ 1

Значение хранится там где-то на основе этого вызова: #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

Сообщение об исключении # является описательной частью:

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

Итак, чтобы получить тип данных, которые вы ищете, вы можете сделать что-то вроде следующего:

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

Ответ 2

@Ответ SaraVessels ближе к тому, что вы хотите, но я думал, что готовая альтернатива может помочь и другим.

Для скриптов из нас рубин поставляется с двумя удобными глобальными (ну, как ни крути, я думаю), $! и [email protected], которые указывают на последнее исключение и последнее исключение.

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

выведет:

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

Это не очень явное, но удобное в интерактивных или очень прототипических настройках.

Ruby stdlib включает 'English' модуль (да, в верхнем регистре), с которым вы могли бы сделать

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

Его странно, и я никогда не использовал его, но, может быть, кто-то будет (y | ier) с этим.