Analyzing Runtime Errors

Objective

After completing this lesson, you will be able to laufzeitfehler analysieren

ABAP-Kurzdump

Die Notwendigkeit für Debugging

Es lässt sich nicht vermeiden, dass in Programmen Fehler auftreten. Diese Fehler können sich aber auf unterschiedliche Weise bemerkbar machen. Wenn ein Benutzer eine fehlerhafte Anwendung startet, kann sie abstürzen, es können unerwartete Ereignisse auftreten oder es kann überhaupt nichts passieren. Aus der Sicht der Benutzer, also auf der Ebene der Benutzungsoberfläche, ist es unmöglich zu erkennen, wie und warum dieser Fehler aufgetreten ist.

Als Entwickler müssen Sie das Programm nun genauer und zeilenweise untersuchen, um festzustellen, welche Anweisungen und Kombinationen von Werten in den verschiedenen Programmvariablen den Fehler verursacht haben. Hier kommt der Debugger ins Spiel.

Laufzeitfehler

ABAP-Code, der eine Anweisung enthält, die durch Null dividiert wird

Es ist wichtig, beim Schreiben von ABAP-Code regelmäßig eine Syntaxprüfung durchzuführen. Allerdings ist eine korrekte Syntax nicht immer eine Garantie dafür, dass Ihr Programm zur Laufzeit auch erfolgreich ausgeführt werden kann.

Beispielsweise können Berechnungen in Ihrem Programm abhängig von den verwendeten Werten ein Problem verursachen. Die Abbildung „In Programmen mit korrekter Syntax können Probleme auftreten" zeigt ein Programm, das zwar syntaktisch korrekt ist, aber dennoch einen Laufzeitfehler verursacht.

ABAP-Kurzdump

Screenshot eines Kurzdumps mit Informationen zum Fehler

Wenn die Laufzeitumgebung auf eine nicht ausführbare Anweisung stößt, bricht sie das Programm ab und löst einen Laufzeitfehler aus. Jeder Laufzeitfehler wird mit einem Namen bezeichnet und einer bestimmten Fehlersituation zugeordnet. Die Laufzeitumgebung bricht das Programm ab, wenn ein Laufzeitfehler nicht abgefangen wird. Der ABAP-Laufzeitfehler kann ab ABAP 7.53 im ABAP Runtime Error Viewer angezeigt werden.

Der ABAP Runtime Error Viewer kann über verschiedene Einstiegspunkte geöffnet werden:

  • Wenn der Fehler beim Ausführen der ABAP-Anwendung auftritt, wird in der unteren rechten Ecke ein Dialog angezeigt. Wählen Sie Anzeigen, um den Fehler anzuzeigen.
  • Doppelklicken Sie in der Sicht Feed-Reader auf den Eintrag für den Laufzeitfehler.

Von der Symbolleiste aus können Sie zu der Quelltextposition navigieren, an der der Dump aufgetreten ist, und den Link zum Dump teilen.

Screenshot der Drucktasten „Zum Quellcode navigieren“ und „Link zum Sichern freigeben“
Screenshot des Kontextmenüs nach Rechtsklick auf den Quelltext im Kurzdump

Unten im Editor befinden sich drei Registerkarten:

  1. Die erste liefert folgende Informationen:

    • Kopfdaten
    • Fehleranalyse
    • Informationen darüber, wo das Programm abgebrochen wurde
    • Quelltextauszug
    • Die Zeile, in der der Fehler aufgetreten ist, wird hervorgehoben. Wählen Sie die Zeile, um zum Fehler im Quelltext zu navigieren.
    • Aktive Aufrufe/Ereignisse
  2. Die Registerkarte Langtext enthält die vollständigen Dump-Informationen. Es unterstützt die Funktionen „Gliederung" und „Schnellübersicht" (Strg+O auf Ihrer Tastatur).

  3. Die Registerkarte Unformatierte Anzeige stellt die Dump-Informationen in einem technischen Format bereit, das nur für spezielle Analysesituationen erforderlich ist.

Über einen Kurzdump können Sie auch direkt zum ABAP Debugger navigieren, um die Werte der Variablen kurz vor dem Auftreten des Laufzeitfehlers einzusehen.

Laufzeitfehler sind völlig normal. Sie werden Ihnen wahrscheinlich bei der Entwicklung Ihrer Programme häufig begegnen. Dennoch sollten Sie Laufzeitfehler soweit wie möglich vermeiden. Ein Benutzer in Ihrem Produktivsystem kann verwirrt sein, wenn er einen Laufzeitfehler sieht, z.B. den Fehler in der Abbildung. Der Benutzer versteht möglicherweise keinen Verweis auf die ABAP-Anwendung und die dargestellten technischen Informationen.

Vermeiden von Laufzeitfehlern

Diagramm, das den logischen Ablauf einer Methode mit bedingter Verzweigung zeigt, um einen Kurzdump zu vermeiden
Beispielimplementierung einer Methode mit bedingter Verzweigung, um einen Kurzdump zu vermeiden

Im obigen Beispiel wurde eine Logik hinzugefügt, um den Laufzeitfehler "Division durch Null" zu vermeiden.

Bedingte Logik zur Vermeidung eines Laufzeitfehlers verwenden

Unternehmensszenario

Einer Ihrer Kollegen hat ein Programm entwickelt, das die durchschnittliche Anzahl der verbleibenden Urlaubstage für jeden verbleibenden Monat im Jahr berechnet. Ein anderer Kollege hat erwähnt, dass das Programm seltsam reagiert, wenn für das Jahr keine Monate mehr verbleiben. Testen Sie das Programm, und nehmen Sie notwendige Änderungen vor, um sicherzustellen, dass es unter allen Umständen funktioniert.

Notiz

In dieser Übung bezieht sich XX auf Ihre Nummer.

Schritte

  1. Legen Sie in Ihrem Paket eine neue ABAP-Klasse mit dem Namen ZCL_XX_DUMP an. Stellen Sie sicher, dass es das Interface IF_OO_ADT_CLASSRUN verwendet. Wenn Sie aufgefordert werden, die Klasse einem Transportauftrag zuzuordnen, verwenden Sie den Transportauftrag, den Sie in der vorherigen Aufgabe angelegt haben.

    1. Wählen Sie FileNewABAP Class.

    2. Geben Sie Ihr Paket ZS4D100_XX ein

    3. Geben Sie den Namen ZCL_XX_DUMP und eine Beschreibung für Ihre Klasse ein.

    4. Wählen Sie Hinzufügen... (neben dem Gruppenrahmen Schnittstellen).

    5. Geben Sie den Filtertext IF_OO_ADT_CLASSRUN ein. Doppelklicken Sie auf den passenden Eintrag in der Trefferliste.

    6. Wählen Sie Next.

    7. Wählen Sie aus Aufträgen, an denen ich beteiligt bin, und Ihren eigenen Transportauftrag.

    8. Wählen Sie Finish.

  2. Fügen Sie in if_oo_adt_classrun~main( ) den folgenden Quelltext hinzu:

    1. Geben Sie im Editor zwischen METHOD if_oo_adt_classrun~main und ENDMETHOD folgendes Coding ein:

      Code Snippet
      123456
      DATA: lv_mths TYPE i VALUE 10, "No. of months remaining in year lv_hols TYPE i VALUE 20, "No. of days untaken vacation lv_avg_hols TYPE i. lv_avg_hols = lv_hols / lv_mths. out->write( |Average vacation days per month { lv_avg_hols }| ).
  3. Aktivieren und testen Sie die Klasse.

    1. Aktivieren Sie die Klasse mit der Tastenkombination Strg + F3.

    2. Führen Sie die Klasse mit der Taste F9aus.

    Ergebnis

    Das Programm gibt durchschnittliche Anzahl an verbleibenden Urlaubstagen pro Monat aus.
  4. Ändern Sie das Testprogramm, prüfen Sie das Ergebnis, wenn 0 Monate im Jahr verbleiben und der Mitarbeiter 20 ungenutzte Urlaubstage hat.

    1. Setzen Sie den Wert von lv_mths auf 0.

    2. Wählen Sie Aktivieren (Strg+F3).

    3. Führen Sie das Programm mit F9aus.

    Ergebnis

    Das Programm wird beendet und zeigt die Details eines Laufzeitfehlers an.
  5. Analysieren Sie den Laufzeitfehler, um das Problem ausfindig zu machen. Warum ist dieser Fehler aufgetreten?

    1. Führen Sie das Programm mit F9aus.

    2. Eclipse zeigt unten rechts ein Dialogfenster mit dem Titel ABAP-Laufzeitfehler an.

    3. Klicken Sie auf den Link Anzeigen, um den Fehler zu analysieren.

    4. Blättern Sie nach unten, um zu sehen, was passiert ist und welche Zeile den Fehler verursacht hat.

    Der Fehler ist aufgetreten, da es mathematisch unzulässig ist, durch null zu dividieren.

  6. Wechseln Sie in den ABAP Editor.

    1. Wählen Sie die Registerkarte ZCL_S4D100_XX_DUMP.

  7. Um den Laufzeitfehler zu vermeiden, implementieren Sie eine Bedingung, damit das Programm den folgenden Text ausgibt, wenn keine Monate mehr übrig sind: Bitte fragen Sie, ob Sie Ihren Resturlaub prolongieren können. Führen Sie ansonsten die Berechnung wie zuvor aus, und geben Sie das Ergebnis aus.

    1. Geben Sie um die vorhandene Berechnung den folgenden Quelltext ein.

      Code Snippet
      123456
      IF lv_mths NE 0. lv_avg_hols = lv_hols / lv_mths. out->write( |Average vacation days per month { lv_avg_hols }| ). ELSE. out->write( |Please ask to roll over remaining vacation| ). ENDIF.
    2. Aktivieren und testen Sie nun das Programm.

      Code Snippet
      1234567891011121314151617181920212223242526
      * Full Solution Code CLASS zcl_s4d100_dump DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES if_oo_adt_classrun . PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zcl_s4d100_dump IMPLEMENTATION. METHOD if_oo_adt_classrun~main. DATA: lv_mths TYPE i VALUE 0, "No. of months remaining in year lv_hols TYPE i VALUE 10, "No. of days untaken vacation lv_avg_hols TYPE i. IF lv_mths <> 0. lv_avg_hols = lv_hols / lv_mths. out->write( |Average vacation days per month { lv_avg_hols }| ). ELSE. out->write( |Please ask to roll over remaining vacation!| ). ENDIF. ENDMETHOD. ENDCLASS.

      Übung