Inhaltsverzeichnis

Abfrage von TAA-Returncodes

Achtung, Baustelle!

In COBOL

In Cobol ist es nur über den Returncode auf einfache Art möglich, eine Fehlersituation im Programm abfragbar zu machen. Deshalb setzen alle EXEC TAA-Anweisungen, in denen eine Fehlersituation auftreten kann, den Returncode entweder als IM-RC-<Code> oder OM-RC-<Code>: OM-RC für Objektoperationen, IM-RC für andere. Alle IM-RC und OM-RC-Felder sind Bedingungsnamen (88er-Einträge) unter derselben Cobol-Variablen.

Eigentlich sollte für die Abfrage immer der Returncode abgefragt werden, der dem Anweisungstyp entspricht, also OM-RC für Objektoperationen, IM-RC für andere. Durch dass aber alle Returncodes unterhalb desselben Cobol-Felds definiert sind, blieb es in Cobol ohne Folge, wenn versehentlich der falsche Returncode abgefragt wurde, also z.B. OM-RC-ERROR statt IM-RC-ERROR.

In Cobol wird bei jeder EXEC-TAA Anweisung der Returncode zurückgesetzt. D.h. selbst wenn die Anweisung keinen Returncode setzt, kann es nicht vorkommen, dass nach einer EXEC TAA Anweisung ein Fehlercode einer vorhergehenden Anweisung noch vorliegt.

In Cobol ist es üblich, die weitere Verarbeitung vom Returncode einer Objektoperation abhängig zu machen, z.B.

   EXEC TAA GET FIRST MYOBJ END-EXEC
   IM OM-RC-EOL
   THEN
       SET TC-STATE-FEHLER OF ME TO TRUE
       EXEC TAA SET AND RAISE SEVERE GROUP MYGRP CODE 01
            ARGUMENTS(TC-LASTOM-OBJECT, TC-LASTOM-OPERATION)
       END-EXEC
    ELSE
    PERFORM SECTION-A
   END-IF

Außerdem gibt es in Cobol Variablen, die Namen und Art der zuletzt ausgeführten Objektoperation enthalten (s. obiges Beispiel, TC-LASTOM-OBJECT und -OPERATION).

In C#

In TAA-Modulen, die mit C# native implementiert sind, gibt es keine allgemeine Returncode-Variable. Normalerweise werden in Fehlersituationen Conditions aufgeworfen, die entweder im Programm behandelt werden können, oder zu einem Abbruch der Verarbeitung führen. Dieses Vorgehen macht das Bestücken von Returncode-Feldern sowie deren Abfrage überflüssig.

Eine C#-Implementierung des o.g. Codes könnte damit z.B. so aussehen:

    var rec = MyObj.FirstOrDefault();
    if (rec == null) {
       this.State.Active = StateEnum.Fehler;
       this.Condition.New<Mldg_Aarch.MyGrp.Message1>(SeverityEnum.Severe, MyObj.Name, "Get").Raise();
    }
    SectionA();

Aus dem Cobol-Code im Rahmen der Migration solchen Code zu erzeugen, ist leider nicht möglich, da hierfür zu viele Annahmen über Inhalt und Auswirkung der mglw. kombinierten Bedingungen und verschachtelten Anweisungen getroffen werden müssten. Um trotzdem Code wie in obigem Cobol-Beispiel migrieren zu können, gibt es in migrierten Cobol-Modulen die Klasse LastOmOperation, die bei Objektoperationen bestückt wird und die Informationen über die zuletzt ausgeführte Objektoperation zur Verfügung stellt. Damit wird das Cobol-Beispiel in migriertem Code so aufgelöst:

    this.Data.MyObj.FirstOrDefault()?.CopyLocal(MyObj);
    if (this.LastOmOperation.IsEOL) {
       this.State.Active = StateEnum.Fehler;
       this.Condition.New<Mldg_Aarch.MyGrp.Message1>(SeverityEnum.Severe, LastOmOperation.ObjectName, LastOmOperation.Code).Raise();
    } else {
        SectionA();
    }

Die Klasse LastOmOperation wird jedoch nur für Objektoperationen bestückt, nicht für andere, z.B. Modulaufrufe, GevoProperty-Abfragen, usw. Das führte bereits zu der Situation, dass bei der Abfrage von OM-RC nach anderen als Objektoperationen fälschlicherweise der Returncode der letzen Objektoperation ausgewertet und die Verarbeitung fälschlicherweise abgebrochen wurde.

Bei der Abfrage von IM-RC stellt sich das Problem etwas anders dar, da es hierfür auch in migriertem C#-Code keinen Ersatz gibt. Da eine TAA-Anweisung, die keine Fehler-Condition erzeugt hat, erfolgreich ausgeführt wurde, hat die Abfrage von IM-RC-OK immer den Wert „true“, von IM-RC-ERROR immer den Wert „false“. In C#-Modulen führt dies bei jeder Abfrage von if (false) zu einer Warnung „warning CS0162: Unreachable code detected“.

Anpassungen bei Abfrage von nicht verfügbarem Returncode

Hiervon betroffene Abfragen sind solche, die den Returncode von nicht auf ein Taa-Objekt bezogenen Anweisungen auswerten (CALL, GET GEVO-PROPERTY, CONDITION, …), oder die nur Informationen über ein Objekt beschafft haben (GETINFO OBJECT).

Anhand der statischen Code-Analyse wird versucht, überflüssige Abfragen nicht zu generieren, und bei Abfragen, in denen der Erfolgsfall behandelt wird, darauf hinzuweisen, dass diese vereinfacht werden können. Falls die Returncode-Abfrage nicht entfernt werden kann, wird, um Fehler zu vermeiden, auf jeden Fall die Information in LastOmOperation zurückgesetzt, sodass die Abfrage des Returncodes immer OK liefern wird.

Die Hinweise werden mit MIG_NOTE versehen, und können bei entsprechenden Einstellungen in VisualStudio/Resharper über die Aufgabenliste abgearbeitet werden: mig_check_todo.jpg