Skip to content
Back to Blog

So liest du einen Stack Trace und behebst den Fehler

Ein Stack Trace wirkt wie Rauschen, bis du weißt, wie man ihn liest. Dieser Leitfaden entschlüsselt Traces in Python und JavaScript und zeigt, wie du die eigentliche Fehlerzeile findest.

SZ
Founder, Molixa
11 min read
Teilen
So liest du einen Stack Trace und behebst den Fehler
Table of contents8 sections

Wenn Sie einen Stacktrace in ein Suchfeld einfügen und denken „Erkläre mir einfach diesen Fehler-Stacktrace“, stellen Sie eigentlich zwei Fragen: Was ist kaputtgegangen und welche Zeile meines Codes hat es verursacht. Ein Stacktrace beantwortet beides, aber nur, wenn Sie ihn in der richtigen Reihenfolge lesen. Diese Anleitung vermittelt die allgemeine Fähigkeit, jeden Trace zu entschlüsseln, in Python oder JavaScript, sodass Sie aufhören zu raten und anfangen zu reparieren.

Die meisten Tutorials beantworten einen bestimmten Fehler und lassen Sie beim nächsten im Stich. Die Fähigkeit, die tatsächlich übertragbar ist, ist das Lesen des Traces selbst: zu wissen, wo die eigentliche Ursache liegt, welche Frames ignoriert werden sollten und wie man vierzig Zeilen Fachjargon in einen einzigen Satz Diagnose verwandelt. Diese Fähigkeit funktioniert bei jedem Fehler, auf den Sie jemals stoßen werden.

Was ein Stack Trace eigentlich ist#

Ein Stack Trace ist eine Momentaufnahme des Aufrufstapels zum Zeitpunkt des Programmabsturzes. Er listet jede Funktion auf, die gerade ausgeführt wurde, in der Reihenfolge ihres Aufrufs, sowie den Fehlertyp und die Fehlermeldung an der Stelle des Fehlers. Wenn Sie ihn richtig lesen, zeigt er direkt auf die fehlerhafte Zeile.

Stellen Sie ihn sich als eine Kette von "wer hat wen aufgerufen" vor. Ihr Programm startet in main, ruft processOrder auf, das wiederum chargeCard aufruft, und dort tritt der Fehler auf. Der Trace zeichnet die gesamte Kette auf, sodass Sie vom Symptom zur Ursache zurückverfolgen können.

Zwei Teile sind am wichtigsten:

  • Der Ausnahmetyp und die Meldung: welche Art von Fehler aufgetreten ist (ein TypeError, ein KeyError, eine Nullreferenz) und eine kurze, verständliche Beschreibung.
  • Die Frames: die geordnete Liste der Funktionsaufrufe, jeweils mit Dateiname und Zeilennummer.

Kurzer Tipp: Die Fehlermeldung sagt Ihnen, was schiefgelaufen ist. Die Frames sagen Ihnen, wo. Sie brauchen fast immer beides, um den Fehler zu beheben, und Leute, die nicht weiterkommen, lesen meist nur eines davon.

Wie man einen Stacktrace von oben nach unten liest#

Hier ist der Teil, der viele verwirrt: Python und JavaScript ordnen ihre Traces in entgegengesetzte Richtungen. Wenn Sie die Richtung richtig haben, ergibt sich alles andere von selbst.

Python: von unten nach oben lesen#

In Python wird der Trace mit dem ältesten Aufruf zuerst und dem neuesten Aufruf zuletzt ausgegeben. Der Header sagt Traceback (most recent call last), was die gesamte Anweisung ist. Die eigentliche Ausnahme ist die letzte Zeile, und die Codezeile, die sie ausgelöst hat, steht direkt darüber.

Traceback (most recent call last):
  File "app.py", line 42, in <module>
    main()
  File "app.py", line 30, in main
    total = calculate_total(cart)
  File "app.py", line 18, in calculate_total
    return sum(item["price"] for item in cart)
KeyError: 'price'

Beginnen Sie unten. KeyError: 'price' bedeutet, dass ein Dictionary keinen Schlüssel price hatte. Die Zeile direkt darüber zeigt genau, wo: Zeile 18, innerhalb von calculate_total, in diesem Generatorausdruck. Alles oberhalb von Zeile 18 zeigt nur, wie das Programm dorthin gelangt ist. Sie beheben Zeile 18 (oder die Daten, die sie speist), nicht main.

JavaScript: von oben nach unten lesen#

JavaScript dreht es um. Die Fehlermeldung steht in der ersten Zeile, und der oberste Frame ist der Ort, an dem der Fehler ausgelöst wurde. Sie lesen nur so weit nach unten, wie Sie müssen, um Ihren eigenen Code zu erreichen.

TypeError: Cannot read properties of undefined (reading 'name')
    at renderUser (app.js:24:18)
    at renderList (app.js:51:9)
    at App (app.js:78:5)
    at react-dom.production.min.js:118:188

Die erste Zeile ist die Diagnose: Es wurde versucht, .name auf einem Wert zu lesen, der undefined war. Der erste Frame, renderUser in Zeile 24, ist der Ort, an dem es passiert ist. Die Frames darunter sind die Aufrufer. Der unterste Frame hier befindet sich in react-dom, Bibliothekscode, den Sie nicht geschrieben haben, also überspringen Sie ihn.

Finding the Line That Actually Broke#

The single most useful habit is this: scan the frames and find the first one that points to your file, not a library or the runtime. That frame is almost always where you need to look first.

A real trace is a sandwich. The top (JS) or bottom (Python) is the raw exception. The middle is a mix of your code and framework code. The trick is filtering:

  • Ignore framework frames unless every frame is framework code (then you are likely calling an API wrong).
  • Find your first frame: the topmost JS frame or bottommost Python frame with your own file path and line number.
  • Open that line and read the error message against what the line is doing.

Match the message to the line. KeyError: 'price' next to item["price"] means the key is missing. Cannot read properties of undefined (reading 'name') next to user.name means user is undefined. The message names the broken operation; the line shows where you wrote it.

Reading the error message itself#

The message is a compressed sentence. Decode the common ones and you have decoded most crashes you will meet.

Error message fragmentWhat it meansFirst thing to check
Cannot read properties of undefined (reading 'x')You accessed .x on something that was undefinedWhy is the object empty or not loaded yet
KeyError: 'x' (Python)A dict has no key 'x'Spelling, or whether the key always exists
TypeError: 'NoneType' object is not subscriptableYou indexed into NoneWhat returned None instead of a list/dict
IndexError: list index out of rangeYou asked for an item past the end of a listLoop bounds, or an empty list
is not a function (JS)You called something that is not callableA typo, or a value that is not what you think
Maximum call stack size exceededInfinite recursionA function calling itself with no base case

Ein wiederholbarer Debugging-Workflow#

Sobald du einen Trace lesen kannst, baue ihn in eine Routine ein, sodass du jedes Mal die gleichen fünf Schritte machst, anstatt in Panik zu verfallen. Dieser Workflow ist der Unterschied zwischen einer Fünf-Minuten-Behebung und einer Stunde Herumirren.

  1. Lies zuerst den Ausnahmetyp und die Meldung. Benenne den Fehler in einfachen Worten, bevor du etwas anfasst.
  2. Finde deinen ersten Frame. Unten in Python, oben in JavaScript. Diese Datei und Zeilennummer sind der Ausgangspunkt.
  3. Öffne diese Zeile und stelle eine Hypothese auf. "Diese Variable ist hier undefiniert, weil der Fetch noch nicht aufgelöst wurde." Ein Satz.
  4. Überprüfe mit einem Wert, nicht mit einer Vermutung. Drucke oder logge die verdächtige Variable direkt vor der fehlschlagenden Zeile. Bestätige, dass sie das ist, was die Meldung behauptet.
  5. Behebe die Ursache, nicht das Symptom. Ein Null-Guard verhindert den Absturz, aber frage warum der Wert null war. Die eigentliche Lösung liegt meist einen Frame weiter oben.

Dieser letzte Punkt ist der häufigste Fehler. Eine Zeile in einen try/except oder einen Optional-Chaining ?. zu packen, stoppt den Absturz, ohne etwas zu beheben. Der Trace hat dir einen kostenlosen Hinweis gegeben: Der Wert war upstream falsch. Folge ihm.

Warnung: "Behebe" niemals einen Trace, indem du die Zeile löschst, auf die er zeigt, oder jede Ausnahme stillschweigend abfängst. Du entfernst nicht den Fehler, du verbindest dir selbst die Augen für den nächsten.

Wenn die Trace-Punkte nur auf Bibliothekscode zeigen#

Manchmal liegt jeder Frame innerhalb eines Frameworks oder einer Abhängigkeit und keiner zeigt auf Ihre Datei. Das ist verwirrend, hat aber eine klare Bedeutung: Sie haben der Bibliothek falsche Eingaben übergeben oder sie falsch aufgerufen. Die Bibliothek ist in Ihrem Namen abgestürzt.

In diesem Fall betrachten Sie den tiefsten Frame, der die Grenze zwischen Ihrem Code und dem der Bibliothek berührt. Ein Datenbanktreiber, der bei einer fehlerhaften Abfrage auslöst, ein JSON-Parser, der bei einem defekten String auslöst, ein Router, der bei einer schlechten Routendefinition auslöst. Die Behebung liegt in dem Wert oder Aufruf, den Sie übergeben haben, auch wenn die sichtbare Explosion im Code der Bibliothek stattfindet.

Asynchroner Code fügt eine weitere Komplikation hinzu. Promises, Callbacks und Threads können Traces erzeugen, die "springen", weil der Fehler weit entfernt vom ursprünglichen Aufruf auftritt. Moderne Laufzeitumgebungen fügen asynchrone Frames zur Hilfe hinzu, aber wenn ein Trace unmöglich kurz oder zusammenhanglos wirkt, liegt der wahre Ursprung möglicherweise in einem nicht abgewarteten Promise oder einem anderweitig verschluckten Fehler.

Lassen Sie sich einen Code-Erklärer helfen#

Das Lesen von Stacktraces ist eine Fähigkeit, die anfangs langsam ist, bis sie schnell wird. Wenn Sie auf einen unbekannten Fehler in einer Sprache stoßen, die Sie selten verwenden, spart es Zeit, das Ganze in ein Tool einzufügen, das es in einfachem Deutsch erklärt. Unser kostenloser Code-Erklärer nimmt einen rohen Traceback und gibt den Fehlertyp, die wahrscheinliche Ursache und die relevante Zeile aus, in den Modi Anfänger bis Senior.

Der ehrliche Hinweis: Eine KI-Erklärung ist eine starke Hypothese, kein Urteil. Sie kann einen ungewöhnlichen Stack falsch interpretieren oder eine plausibel klingende Ursache erfinden. Behandeln Sie die Antwort wie den schnellen Hinweis eines erfahrenen Kollegen, der in die richtige Richtung zeigt, den Sie aber dennoch anhand der tatsächlichen Zeile und Werte überprüfen.

Zwei schnelle Gewohnheiten zur Überprüfung halten Sie sicher:

  • Überprüfen Sie die Zeilennummer. Wenn das Tool sagt, der Fehler sei in Zeile 18, öffnen Sie Zeile 18 und bestätigen Sie, dass die Nachricht zum Code passt.
  • Achten Sie auf erfundene APIs. Wenn ein Lösungsvorschlag eine Methode oder ein Paket nennt, das Sie nicht kennen, suchen Sie danach, bevor Sie ihm vertrauen. Erfundene Funktionsnamen sind die häufigste Art, wie diese Tools in die Irre führen.

Bei Fehlern, die eigentlich Musterprobleme sind, wie einem Regex, der einen Fehler wirft oder nicht matcht, kombinieren Sie die Erklärung mit einem Live-Regex-Tester zum Debuggen Ihres Musters, um genau zu sehen, welche Zeichen matchen. Und wenn der Erklärer eine verwirrende JSON-Nutzlast im Fehler liefert, formatieren Sie sie mit dem JSON-Formatter, um die Struktur lesbar zu machen, bevor Sie den Trace weiterlesen.

Alles zusammengefasst#

Wenn Sie das nächste Mal diesen Fehler-Stack-Trace erklären müssen, haben Sie einen Prozess statt Panik. Benennen Sie die Ausnahme, lesen Sie in die richtige Richtung (von unten nach oben bei Python, von oben nach unten bei JavaScript), finden Sie den ersten Frame in Ihrem eigenen Code und bestätigen Sie Ihre Hypothese mit einem echten Wert, bevor Sie etwas ändern. Der Trace ist kein Rauschen. Es ist eine Karte mit bereits markiertem Ziel.

Das flüssige Lesen von Traces unterscheidet Entwickler, die Fehler in Minuten beheben, von denen, die Nachmittage verlieren. Bauen Sie die Gewohnheit bei kleinen Fehlern auf, und die gruseligen vierzigzeiligen Traces hören auf, gruselig zu sein.

Häufig gestellte Fragen#

Lese ich einen Stacktrace von oben nach unten oder von unten nach oben? Das hängt von der Sprache ab. Python gibt den ältesten Aufruf zuerst und die Ausnahme zuletzt aus, daher liest man ihn von unten nach oben, und die fehlerhafte Zeile steht direkt über der abschließenden Fehlermeldung. JavaScript platziert die Fehlermeldung und den auslösenden Frame oben, daher liest man von oben nach unten. In beiden Fällen sucht man nach dem ersten Frame, der auf den eigenen Code verweist.

Was bedeutet „Cannot read properties of undefined“ eigentlich? Es bedeutet, dass Ihr Code versucht hat, auf eine Eigenschaft oder Methode eines Werts zuzugreifen, der undefined war. Zum Beispiel user.name, wenn user nie zugewiesen wurde. Die Lösung liegt selten in dieser Zeile selbst, sondern darin, herauszufinden, warum der Wert leer war, oft ein Datenladevorgang, der noch nicht abgeschlossen ist, oder ein Objekt, das nie zurückgegeben wurde.

Welche Zeile im Trace sollte ich korrigieren? Suchen Sie den ersten Frame, der auf eine von Ihnen geschriebene Datei verweist, nicht auf eine Bibliothek oder die Laufzeitumgebung. Diese Zeile ist der Ort, an dem der Fehler aufgetreten ist. Die eigentliche Ursache liegt manchmal einen Frame darüber, wo ein falscher Wert übergeben wurde. Lesen Sie daher die Meldung zusammen mit der Zeile und folgen Sie den Daten rückwärts, wenn die Zeile selbst harmlos aussieht.

Kann ich einem KI-Tool vertrauen, das meinen Stacktrace erklärt? Meistens ja, als schnelle Ersteinschätzung. Ein guter Code-Erklärer benennt den Fehlertyp korrekt und zeigt viel schneller auf die richtige Stelle, als wenn Sie in Foren suchen. Behandeln Sie den spezifischen Lösungsvorschlag jedoch als Hypothese: Überprüfen Sie, ob die Zeilennummer mit dem fehlerhaften Code übereinstimmt, und fügen Sie niemals eine vorgeschlagene Methode oder ein Paket ein, dessen Existenz Sie nicht überprüfen können.

Warum zeigt mein Trace nur Bibliothekscode und keine meiner Dateien? Das bedeutet in der Regel, dass Sie einer Bibliothek falsche Eingaben übergeben oder ihre API falsch aufgerufen haben, sodass der Absturz in deren Code für Sie auftritt. Suchen Sie nach dem Grenzframe, in dem Ihr Aufruf in die Bibliothek eintritt, und überprüfen Sie die Werte oder Argumente, die Sie übergeben haben. Die Lösung liegt in Ihrer Eingabe, auch wenn die Explosion in deren Code stattfindet.

Was mache ich mit einem asynchronen oder Promise-Stacktrace, der zusammenhanglos wirkt? Asynchrone Fehler können weit entfernt vom ursprünglichen Aufruf auftauchen, sodass der Trace kurz wirkt oder unerwartet springt. Suchen Sie nach einem nicht abgewarteten Promise oder einem geschluckten Fehler vorgelagert, aktivieren Sie asynchrone Stacktraces, falls Ihre Laufzeitumgebung dies unterstützt, und fügen Sie eine Protokollierung direkt vor dem verdächtigen await ein, um zu bestätigen, welchen Wert Sie tatsächlich an dieser Stelle haben.

More from Molixa

Try Molixa Tools

50+ free AI tools for content creation, SEO, coding, and more. No signup, no watermark.

Explore all tools