infra:NET Expert
 
×
8.5.4 Fehlerquellen und Behandlung
Im Interpretersystem unterscheidet man folgende Arten von Fehlern:
  • Fehler ausgelöst durch einen fehlgeschlagenen Kernsystemaufruf
  • Fehler, die im IS intern auftreten
  • Logische Fehler beim Ausführen der Steuerdatei
Die Fehlerbehandlung erfolgt mittels der Klassen ACIpsError und ACIpsErrorElement. Jedes Objekt der Klasse ACIpsInstance beinhaltet ein Objekt der Klasse ACIpsError. Tritt einer der obengenannten Fehler auf, so stellt das Interpretersystem den Fehler dort ab, um dem Programmierer die Möglichkeit zu geben den Fehler zur Ausgabe zu bringen. Dabei ist es i.A. auch möglich die Aufrufstruktur auszugeben.
Indiz für einen Fehler ist, wenn die Methode Run() mit FALSE zurückkehrt. Die Errorklasse bietet mit den Methoden BuildMsgText() und QueryMsgText() die Möglichkeit einen Hinweistext zum Fehler zu erzeugen und abzufragen (siehe Beispiel oben) und diesen je nach Bedarf auszugeben.
Um die Aufrufstruktur zu generieren, ist jede Funktion oder Methode so zu implementieren, dass sie bei Auftreten eines Fehlers dem Errorobjekt ein ErrorElement hinzufügt. Ist der Fehler die Folge eines Funktions/Methodenaufrufes (Returncode != 0) und bleibt der Returncode unverändert, so ist das Element nur als Level hinzuzufügen. Ändert sich der Returncode so ist das Errorelement mit dem neuen Returncode hinzuzufügen. Werden Fehler durch Kernsystemaufrufe ausgelöst, sollte ein Errorelement für den Kernsystemaufruf hinzugefügt werden. Dabei sollte für das Klassenattribut „ksys“ eingetragen werden. ErrorElemente, die mit AddErrorElement() hinzugefügt werden, können bis zu fünf Stringwerte enthalten, die zum Aufbau eines detaillierteren Fehlerhinweises verwendet werden können.
 
//            --------  ------------
LONG          ACIpsBuf::UpdateBuffer(ULONG ulApplHandle)
//            --------  ------------
{
  LONG lRc = 0;
  ACIpsErrorElement CIpsEE("ACIpsBuf","UpdateBuffer");
 
    if  ( !TST_BIT32(m_ulFlag,ACIPSBF_Locked) )
        {
        lRc = RCIPS_RecordNotLocked;
        AddErrorElement(CIpsEE,lRc,m_scsName);
        return lRc;
        }
 
   m_ulRcDbsCall=DbsUpdate(ulApplHandle,m_lTable,m_scsWorkBuf,m_lISN,TRUE);
    if  ( m_ulRcDbsCall )
        {
        if  ( m_ulRcDbsCall != DBERR_warning_i )
            {
            lRc = (LONG) m_ulRcDbsCall;
              ACIpsErrorElement CIpsEEksys("ksys","DbsUpdate");
            AddErrorElement(CIpsEEksys,lRc);
            lRc = RCIPS_DbsCallFailed;
            AddErrorElement(CIpsEE,lRc,m_scsName,m_scsWorkBuf);
            return lRc;
            }
        }
       
    if  ( m_lBufIndex )
        {
        lRc = SetApplBuffer(ulApplHandle);
        if  ( lRc )
            AddErrorLevel(CIpsEE);
        }
    return lRc;
}
 
Vor der Rückkehr zur rufenden Funktion ermittelt die Run()-Methode, ob ein Fehler aufgetreten ist. Ist im Errorobjekt ein logischer Fehler eingetragen, so wird dieser beibehalten. Ist kein logischer Fehler eingetragen, so prüft das IS die Aufrufstruktur auf Kernsystem oder interne Fehler ab. Ist ein interner IS-Fehler aufgetreten, setzt das IS den logischen Fehler auf den Wert RCIPS_ErrorIS(1). Entdeckt das IS einen Kernsystemfehler, so erhält der logische Fehler den Wert RCIPS_ErrorKS(2).
Logische Fehler, die in der Scriptabarbeitung auftreten, bzw. in den erweiternden DLL’s verwendet werden, dürfen nur Werte > 2 annehmen.
In der Programmierung der externen Funktionen werden logische Fehler mit der Methode ACIpsInstance::SetGeneralError() gesetzt (Achtung: Die externe Funktion sollte diesen Fehlercode auch an die rufende Funktion übergeben). Zum Auslösen eines logischen Fehlers in der Steuerdatei gibt es die Funktion IpsRaiseGeneralError(), siehe unten.
Steuerdateien werden z.B. im Buchungssystem dazu verwendet Buchungsvorgänge zu implementieren. Um bei der Fehlerausgabe das Item, um das es bei dem Buchungsvorgang geht, zur Ausgabe zu bringen gibt es die Funktion IpsSetItemParams(). Bei der Generierung des Fehlerhinweises erfolgt zuerst ein Hinweis auf das beteiligte Item.
Die Fehlerhinweistexte, die auch Platzhalter enthalten können, werden in der Datei sibpps.msg gesucht. Die Identifizierung enthält ein Prefix, z.B. „IPS“ für interne IS-Fehler und eine Nummer. Im Fehlerfall und anschließendem Aufruf von BuildMsgText() versucht das IS auf die Hinweistexte zuzugreifen und sie ggf. mit den Detailparametern zu ergänzen.
Das IS bietet die Möglichkeit im Fehlerfall einen präparierten Fehler zur Ausgabe zu bringen. Dies ist dann von Vorteil, wenn Aufrufe wie z.B. BufUpdateBuffer fehlerhaft ausgeführt werden und die Daten in einen inkonsistenten Zustand geraten. IpsPrepareRcGeneral() setzt diesen präparierten Fehler, sobald ein Funktionsaufruf mit einem Fehler endet, wird der logische Fehler auf den präparierten Fehler gesetzt, unabhängig davon, was der auslösende Fehler war. Ips[Query/Set]PreparedRcPrefixMSG dienen dazu den Messageprefix abzufragen bzw. zu setzen.