Toni: Debugging - Programmdurchlauf aufnehmen?

Hallo,

Stoße beim Debugging immer wieder auf denselben ärgerlichen Fehler.

Und zwar läuft ein [leider recht komplexes] Javascript Programm prinzipiell problemlos - allerdings bockt ein Attribut bei jedem durchschnittlich 20. Programmdurchlauf und wirft einen Fehler aus.

Da das Programm mit Zufallswerten arbeitet, passieren diese Abweichungen auch zufällig - entsprechend ratlos bin ich, was das Debugging angeht - (ist tatsächlich Neuland für mich).

Daher:

kann die Chrome Developer Console (oder irgendein anderer Browser) einen Programmdurchlauf von A-Z speichern, sodass ich den Programmdurchlauf mit den fehlerhaften Parametern gezielt von A-Z aufrufen kann? Bzw. gibt es dafür irgendwelche Plugins?

LG, Toni

  1. ...bzw möchte ich wohl viel eher nur eine Momentaufnahme innerhalb des sonst problemlos laufenden Programms speichern, die ich dann Schritt für Schritt durchspielen kann (daher vor einem bestimmten Funktionsaufruf das Recording starten und es danach wieder beenden)

    1. Lieber Toni,

      ...bzw möchte ich

      des Menschen Wille ist sein Himmelreich.

      Suche nicht nach einer Browserfunktionalität, die Deine spezielle Weltvorstellung erfüllt, sondern nimm das, was in der Welt da ist, um damit das zu tun, was Dich Deinem Ziel näher bringt.

      Jürgen hat Dir ja schon erklärt, dass Du die fraglichen Werte an entsprechender Stelle Deines Scripts in die Console ausgeben lassen kannst. Das sollte Dir genügend Einblick verschaffen, um weitere Erkenntnisse zu sammeln.

      Liebe Grüße

      Felix Riesterer

  2. Hi,

    man kann im Chrome den Zustand speichern, frage mich jetzt aber nicht wo und wie man es auswerten kann.

    Hast Du es mal mit try/catch versucht? Anhand der Fehlermeldung kannst Du ein besseres Fehler-Handling implementieren, ggf. sogar grundsätzlich herausfinden was das Problem ist:

    try {
       // Dein JS
    }
    catch (e) {
      
       console.log(e)
    }
    

    Oder Du definierst es global:

    window.onerror = function() {
      console.log(arguments);
    };
    

    André

    1. Entschuldigung, habe das falsch formuliert.

      Es wirft keinen Fehler aus, es verhält sich allerdings falsch.

      1. Hallo,

        Es wirft keinen Fehler aus, es verhält sich allerdings falsch.

        in einem ersten Schritt gebe ich in meinen Scripten an strategisch sinnvollen Stellen die entscheidenden Variablen mit console.log aus. Über Abfragen kannst du die Ausgaben auch noch auf relevante Situationen beschränken.

        Gruß
        Jürgen

  3. Hallo Toni,

    Da das Programm mit Zufallswerten arbeitet, passieren diese Abweichungen auch zufällig - entsprechend ratlos bin ich, was das Debugging angeht - (ist tatsächlich Neuland für mich).

    Solche Probleme entstehen typischerweise dann, wenn Funktionen oder Klassen zu groß und unübersichtlich werden, und die Abhängigkeiten zwischen den Teilen zu komplex sind.

    Man kann hier nach schnellen Lösungen suchen, und den Code damit vermutlich noch weiter verkomplizieren, oder man kann versuchen, den Code zu strukturieren und möglichst zu zu verteilen, dass Zufallseffekte möglichst isoliert relevant sind.

    Guter Code trennt I/O und Fachlogik, so dass man die Fachlogik Unittests unterziehen kann. Sprich: Ich kann definierte Eingaben hineingeben, und kann dann definierte Ausgaben erwarten. Ich kann dann einen Testtreiber schreiben, der die Funktion mit einer sinnvollen Menge an Eingabekombinationen aufruft, und dann validiert, ob die erwartete Ausgabe stattfindet.

    Code unittestfähig machen ist nicht trivial. Schlüsselelement dafür ist maximale Entkoppelung, und die Fähigkeit, Abhängigkeiten zwischen Komponenten nicht in den Komponenten zu haben, sondern sie von außen, von einer Dirigentenkomponente, hineinzugeben (dependency injection). Sieht man das zum ersten Mal, erklärt man den anderen Programmierer für bekloppt. Sieht man dann aber, wie die Unittests wunderbar durchflutschen und kleine Fehlerchen sofort auffallen, ist man begeistert.

    Altcode, der struppig gebaut ist, muss man dafür aber zumeist neu schreiben.

    Um auf deinen bestehenden Code zurückzukommen: In Chrome gibt es in den Entwicklertools den Performance-Recorder. Der zeigt Dir zu jedem Zeitpunkt an, wie der Callstack ist, d.h. du siehst zumindest, wie die Funktionsaufrufe waren. Variableninhalte siehst Du nicht. Da hilft nur Logging in die Konsole, oder das Setzen von Breakpoints an den vermuteten Fehlerstellen.

    Rolf

    --
    sumpsi - posui - obstruxi
  4. Hallo Leute,

    Ja erstmal euch allen vielen lieben Dank für den wertvollen Input.

    ...alles wirklich sehr komisch, das.

    Ich habe versucht, Code Snippets so weit es geht zu isolieren - aber auch bei exakt denselben Inputs verhält sich das Programm im Browser jedes n-te Mal anders. Ich habe dann bereits an Chrome selbst zu zweifeln begonnen - Firefox sieht die Sache allerdings nicht anders.

    GROOSSES Fragezeichen.

    Werde den Nachmittag jetzt noch damit verbringen, in die Richtung weiterzukommen (heißt 90% der Zeit fassungsloses auf den Bildschirm Gestarre). Sollte ich auf des Pudels Kern stoßen, melde ich mich an dieser Stelle aber nochmal.

    Welche(n) weiterführende Lektüre(n)/Kurs(e) empfehlt ihr bezüglich Unit Tests?

    1. Welche(n) weiterführende Lektüre(n)/Kurs(e) empfehlt ihr bezüglich Unit Tests?

      ... und genau so entstehen übrigens 🐞s!

      Bei weiterführende fehlt ein n! 😂

      Meine derzeitige Stimmung zusammengefasst:

      Und er kommt zu dem Ergebnis:
      Nur ein Traum war das Erlebnis.
      Weil, so schließt er messerscharf,
      nicht sein kann, was nicht sein darf. 
      

      (Christian Morgenstern)

  5. Hallo Leute!

    Alles klar, bin auf des Pudels Kern gestoßen.

    ... was tatsächlich bestätigt, dass nicht sein kann, was nicht sein darf.

    ...und zwar wird eine Klasse einfach nicht (wie im Code eigentlich vorgesehen) angefügt.

    Element.classList.add(Klasse);
    console.log(Element, Klasse);
    
    
    // Diese beiden Zeilen folgen DIREKT aufeinander, dazwischen KEIN weiteres Script
    
    // Konsole spuckt jedes n-te Mal das Element OHNE der Klasse aus (daher rührt das Fehlverhalten)
    // Die von der Konsole ausgespuckte Klasse ist aber KORREKT.
    

    Gibt es zu diesem Verhalten irgendwelche Erfahrungswerte?

    Suche derweil weiter...

    1. Hallo Toni,

      sehr merkwürdig. Ich habe das gerade schnell überprüft - ein add auf die classList sollte sich sofort im class-Attribut des Elements wiederfinden.

      Ein add wird nicht ausgeführt, wenn die Klasse schon vorhanden ist. In diesem Beispiel

      <div id="foo" class="dings">...</div>
      
      <script>
      let fooElem = document.getElementById("foo");
      fooElem.classList.add("dings");
      </script>
      

      würde der add nichts tun.

      Ein add mit einem ungültigen Klassennamen (also z.B. classList.add(" test"); wirft eine Exception. Die würde man im Log sehen, das sollte es also nicht sein.

      Welche konkreten Werte stehen vor dem add im className Attribut des Elements und in der Klasse Variable? Welcher Wert steht nachher in className? Bitte mit Begrenzern ausgeben, z.B. so: console.log("<" + Klasse + ">"). Ich habe keine Ahnung wo Du den Inhalt von Klasse her hast und ob sich da merkwürdige Zeichen einschleichen können.

      Rolf

      --
      sumpsi - posui - obstruxi
  6. Hallo,

    du kannst auch einen conditional breakpoint einsetzen. Dazu in den DevTools im Tab "Sources" rechtsklick auf die Zeilennummer und dort dann "conditional breakpoint" auswähhlen. Da kannst du dann eine Bedingung eintragen. Der Breakpoint wird nur ausgelöst wenn die condition auf true evaluiet wird.

    Viele Grüße Matti

  7. Vielleicht ist Selenium IDE was für dich. Damit kannst du Browseraktionen aufnehmen, Testbedingungen definieren und auch die Ergebnisse debuggen.

    LG andaris