Когда я получаю исключения, это часто происходит из глубины стека вызовов. Когда это происходит, чаще всего настоящая оскорбительная строка кода скрыта от меня:
tmp.rb:7:in `t': undefined method `bar' for nil:NilClass (NoMethodError)
from tmp.rb:10:in `s'
from tmp.rb:13:in `r'
from tmp.rb:16:in `q'
from tmp.rb:19:in `p'
from tmp.rb:22:in `o'
from tmp.rb:25:in `n'
from tmp.rb:28:in `m'
from tmp.rb:31:in `l'
... 8 levels...
from tmp.rb:58:in `c'
from tmp.rb:61:in `b'
from tmp.rb:64:in `a'
from tmp.rb:67
Это усечение "... 8 уровней ..." доставляет мне много хлопот. У меня нет особого успеха в поиске в Google: как мне сказать ruby, что я хочу, чтобы дампы включали полный стек?
ruby
exception
stack-trace
Sniggerfardimungus
источник
источник
Ответы:
Исключение # backtrace содержит весь стек:
(Вдохновлено блогом Питера Купера Ruby Inside )
источник
raise
. Нет необходимости явно указывать исключение, которое вы хотите поднять.Вы также можете сделать это, если вы хотите простой однострочный:
источник
raise
можно использовать без аргументов. Также я не знал, чтоrescue
будет правильно трактоваться как однострочник. Я также полностью игнорирую эти глобальные переменные как$!
.puts "this line was reached by #{caller.join("\n")}"
y caller
чтобы напечатать вывод, как трассировка стека Java.caller(0,2)
вернет две последние записи в трассировке стека. Отлично подходит для вывода сокращенных стековых трасс.Это дает описание ошибки и красивую чистую трассировку с отступом:
источник
IRB имеет настройку для этой ужасной «функции», которую вы можете настроить.
Создайте файл с именем
~/.irbrc
, включающим следующую строку:Это позволит вам увидеть
irb
как минимум 100 кадров стека . Мне не удалось найти эквивалентную настройку для неинтерактивной среды выполнения.Подробную информацию о настройке IRB можно найти в книге «Кирка» .
источник
Один лайнер для callstack:
Один лайнер для callstack без всех драгоценных камней:
Один лайнер для callstack без всех драгоценных камней и относительно текущего каталога
источник
Это имитирует официальную трассировку Ruby, если это важно для вас.
Забавно, что он не обрабатывает «необработанное исключение» должным образом, сообщая о нем как «RuntimeError», но местоположение является правильным.
источник
Я получал эти ошибки, когда пытался загрузить свою тестовую среду (с помощью rake test или autotest), и предложения IRB не помогли. В итоге я завернул весь файл test / test_helper.rb в блок begin / rescue, и это все исправило.
источник
[исследуйте все обратные пути потоков, чтобы найти виновника]
Даже полностью расширенный стек вызовов по-прежнему может скрыть от вас фактическую строку кода, когда вы используете более одного потока!
Пример: один поток выполняет итерацию ruby Hash, другой поток пытается его изменить. БУМ! Исключение! И проблема с трассировкой стека, которую вы получаете при попытке изменить «занятый» хеш, состоит в том, что она показывает цепочку функций вплоть до того места, где вы пытаетесь изменить хеш, но она НЕ показывает, кто в данный момент выполняет ее параллельно ( кому это принадлежит)! Вот способ выяснить это путем печати трассировки стека для ВСЕХ запущенных потоков. Вот как вы это делаете:
Приведенный выше фрагмент кода полезен даже для образовательных целей, поскольку он может показать вам (например, рентген), сколько потоков у вас на самом деле (по сравнению с тем, сколько, как вы думаете, у вас есть - довольно часто эти два числа разные);
источник
Вы также можете использовать обратную трассировку Ruby gem (я автор):
источник