Quando recebo exceções, geralmente é do fundo da pilha de chamadas. Quando isso acontece, na maioria das vezes, a linha de código incorreta real está oculta:
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
Esse truncamento "... 8 níveis ..." está me causando muitos problemas. Não estou tendo muito sucesso pesquisando no Google: como posso dizer ao ruby que quero que os dumps incluam a pilha completa?
ruby
exception
stack-trace
Sniggerfardimungus
fonte
fonte
Respostas:
A exceção # backtrace possui toda a pilha:
(Inspirado no blog Ruby Inside de Peter Cooper )
fonte
raise
. Não há necessidade de especificar explicitamente a execução que você deseja aumentar.Você também pode fazer isso se desejar uma linha única:
fonte
raise
pode ser usado sem argumentos. Nem eu sabia querescue
isso seria tratado corretamente como uma linha. Eu também ignoro totalmente esses vars globais como$!
.puts "this line was reached by #{caller.join("\n")}"
y caller
para imprimir a saída como rastreamento de pilha Java.caller(0,2)
retornaria as duas entradas mais recentes no rastreamento de pilha. Bom para a saída de traços de pilha abreviados.Isso produz a descrição do erro e o bom e limpo stacktrace:
fonte
O IRB possui uma configuração para esse "recurso" terrível, que você pode personalizar.
Crie um arquivo chamado
~/.irbrc
que inclua a seguinte linha:Isso permitirá que você veja 100 quadros de pilha em
irb
, pelo menos. Não consegui encontrar uma configuração equivalente para o tempo de execução não interativo.Informações detalhadas sobre a personalização do IRB podem ser encontradas no livro Pickaxe .
fonte
Um revestimento para pilha de chamada:
Um forro para pilha de chamadas sem todas as gemas:
Um forro para pilha de chamadas sem todas as gemas e em relação ao diretório atual
fonte
Isso imita o rastreio oficial do Ruby, se isso é importante para você.
Divertidamente, ele não lida com 'exceção não tratada' corretamente, relatando-o como 'RuntimeError', mas o local está correto.
fonte
Eu estava recebendo esses erros ao tentar carregar meu ambiente de teste (via rake test ou autoteste) e as sugestões do IRB não ajudaram. Acabei envolvendo meu test / test_helper.rb inteiro em um bloco de início / resgate e isso corrigiu as coisas.
fonte
[examine todos os backtraces de threads para encontrar o culpado]
Mesmo a pilha de chamadas totalmente expandida ainda pode ocultar a linha de código incorreta real quando você usa mais de um thread!
Exemplo: um segmento está iterando o ruby Hash, outro está tentando modificá-lo. ESTRONDO! Exceção! E o problema com o rastreamento de pilha que você obtém ao tentar modificar o hash 'ocupado' é que ele mostra a cadeia de funções até o local em que você está tentando modificar o hash, mas NÃO mostra quem está iterando no momento ( quem é o dono)! Aqui está a maneira de descobrir isso imprimindo o rastreamento de pilha para TODOS os threads em execução no momento. Aqui está como você faz isso:
O snippet de código acima é útil mesmo para fins educacionais, pois pode mostrar (como raio-x) quantos threads você realmente tem (versus quantos você pensou ter - com bastante frequência esses dois são números diferentes)
fonte
Você também pode usar a gema Ruby de backtrace (eu sou o autor):
fonte