Wenn ich Ausnahmen bekomme, kommt es oft aus der Tiefe des Aufrufstapels. Wenn dies passiert, ist mir die eigentliche fehlerhafte Codezeile meistens verborgen:
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
Diese Kürzung von "... 8 Stufen ..." bereitet mir große Probleme. Ich habe nicht viel Erfolg beim Googeln: Wie kann ich Ruby sagen, dass Dumps den gesamten Stapel enthalten sollen?
ruby
exception
stack-trace
Sniggerfardimungus
quelle
quelle
Antworten:
Ausnahme # backtrace enthält den gesamten Stapel:
(Inspiriert von Peter Coopers Ruby Inside Blog)
quelle
raise
. Sie müssen die Ausführung, die Sie auslösen möchten, nicht explizit angeben.Sie können dies auch tun, wenn Sie einen einfachen Einzeiler wünschen:
quelle
raise
das ohne Argumente verwendet werden kann. Ich wusste auch nicht, dassrescue
dies korrekt als Einzeiler behandelt wird. Ich ignoriere auch diese globalen Vars wie total$!
.puts "this line was reached by #{caller.join("\n")}"
y caller
, um die Ausgabe wie Java-Stack-Trace zu drucken.caller(0,2)
würde die zwei neuesten Einträge in der Stapelverfolgung zurückgeben. Nizza für die Ausgabe von abgekürzten Stacktraces.Dies erzeugt die Fehlerbeschreibung und eine schöne saubere, eingerückte Stapelverfolgung:
quelle
IRB hat eine Einstellung für diese schreckliche "Funktion", die Sie anpassen können.
Erstellen Sie eine Datei mit dem Namen
~/.irbrc
, die die folgende Zeile enthält:Auf diese Weise können Sie
irb
mindestens 100 Stapelrahmen anzeigen . Ich konnte keine entsprechende Einstellung für die nicht interaktive Laufzeit finden.Detaillierte Informationen zur IRB-Anpassung finden Sie im Pickaxe-Buch .
quelle
Ein Liner für Callstack:
Ein Liner für Callstack ohne alle Edelsteine:
Ein Liner für Callstack ohne alle Edelsteine und relativ zum aktuellen Verzeichnis
quelle
Dies ahmt die offizielle Ruby-Spur nach, wenn Ihnen das wichtig ist.
Amüsanterweise wird "nicht behandelte Ausnahme" nicht richtig behandelt und als "RuntimeError" gemeldet, aber der Speicherort ist korrekt.
quelle
Ich habe diese Fehler beim Laden meiner Testumgebung (über Rake-Test oder Autotest) erhalten, und die IRB-Vorschläge haben nicht geholfen. Am Ende habe ich meine gesamte Datei test / test_helper.rb in einen Start- / Rettungsblock eingewickelt, und das hat die Probleme behoben.
quelle
[Untersuchen Sie alle Thread-Backtraces, um den Schuldigen zu finden]
Selbst ein vollständig erweiterter Aufrufstapel kann die tatsächlich fehlerhafte Codezeile vor Ihnen verbergen, wenn Sie mehr als einen Thread verwenden!
Beispiel: Ein Thread iteriert Ruby Hash, ein anderer Thread versucht, ihn zu ändern. BOOM! Ausnahme! Das Problem mit der Stapelverfolgung, die Sie erhalten, wenn Sie versuchen, den "beschäftigten" Hash zu ändern, besteht darin, dass die Funktionskette bis zu der Stelle angezeigt wird, an der Sie den Hash ändern möchten. Es wird jedoch NICHT angezeigt, wer ihn derzeit parallel iteriert ( Wem gehört es)! Hier erfahren Sie, wie Sie dies herausfinden können, indem Sie die Stapelverfolgung für ALLE aktuell ausgeführten Threads drucken. So geht's:
Das obige Code-Snippet ist auch nur für Bildungszwecke nützlich, da es Ihnen (wie Röntgen) zeigen kann, wie viele Threads Sie tatsächlich haben (im Vergleich zu der Anzahl, von der Sie dachten, dass Sie sie haben - ziemlich oft sind diese beiden unterschiedliche Zahlen;)
quelle
Sie können auch Ruby Gem zurückverfolgen (ich bin der Autor):
quelle