SOG-Helpcenter Logo SOG Business - Software

Fehlerbehandlung unter C#


 

Beschreibung


Jedes Programm sollte in geeigneter Art und Weise auf mögliche Fehler reagieren. Da es in komplexen Anwendungen jedoch jederzeit und überall zu Fehlern kommen könnte, erscheint eine Fehlerbehandlung durch Meldung eines Returncodes als Funktionsrückgabewert vollkommen unsinnig, da so niemals der Funktionsrückgabewert sinnvoll genutzt werden könnte, und nach jedem Funktionsaufruf eine Fehlerbehandlung zu programmieren wäre.

C# nutzt für die Behandlung von Fehler "Exceptions". Verarbeitungsroutinen sollten Fehler also IMMER durch Auslösen einer Exception melden:


    if ( refobj==null )
        throw new SOGException( "Kein Objekt gefunden" );

und es dem Aufrufer überlassen, wie dieser auf derartige Fehler reagiert. In einem Kontext, in dem ein Weiterarbeiten nicht möglich ist, kann er z.B. das Programm abbrechen. Läuft die Verarbeitung nur als kleiner Teil einer größeren Anwendung, wie z.B. eines Web-Servers wäre der Abbruch der gesamten Anwendung jedoch nicht vertretbar. In diesem Fall kann der Aufrufer die Fehlermeldung protokollieren, und nur diesen Verarbeitungsschritt beenden.

Abfangen von Fehlern


Das Abfangen von Fehlern kann in bestimmten Situationen sinnvoll sein, wenn z.B. trotz des Fehlens eines Datensatzes weiter gearbeitet werden soll:


    Kunden kd = KundenTable.GetKunde( 1, 4711 );

Die oben gezeigte Anweisung würde z.B. bei Fehlen des Datensatzes 4711 in der Kundentabelle die Verarbeitung abbrechen, und eine Exception des Typs "SOGNoRecordException" an den Aufrufer übergeben.


    Kunden kd;
    try
    {
        kd = KundenTable.GetKunde( 1, 4711 );
    }
    catch ( SOGNoRecordException )
    {
        kd = KundenTable.GetKunde( 1, 4712 );
    }

Das hier gezeigte Konstrukt liest bei Fehlen des Datensatzes 4711 alternativ den Datensatz 4712. Ist auch dieser nicht vorhanden, bricht die Verarbeitung wie im 1. Beispiel mit "SOGNoRecordException" ab.
Hinweis: Dieses Konstrukt kann inzwischen mit der Funktion "GetXXXNoEx" auch geschickter und schöner programmiert werden:

    Kunden kd = KundenTable.GetKundeNoEx( 1, 4711 );
    if ( kd==null )
        kd = KundenTable.GetKunde( 1, 4712 );

Exceptions nicht anonymisieren


Sie sollten jedoch keinesfalls in den Fehler verfallen, Ausnahmefehler zu "anonymisieren":


    Kunden kd;
    try
    {
        kd = KundenTable.GetKunde( 1, 4711 );
    }
    catch ( Exception )
    {
        Console.WriteLine( "Der Datensatz ist nicht vorhanden" );
    }

erscheint bei oberflächlicher Betrachtung korrekt codiert zu sein. Beachten Sie aber, dass die Fehlermeldung "Datensatz nicht vorhanden" auch dann kommt, wenn z.B. die Datenbank, die Datenbanktabelle oder auch nur ein einzelnes Datenfeld nicht vorhanden ist, wenn bei der Konvertierung von Dateninhalten Fehler auftreten oder wenn es zu Netzwerkproblemen kommt.

Geben Sie daher immer die original Exception an den Aufrufer zur Protokollierung weiter!


    Kunden kd;
    try
    {
        kd = KundenTable.GetKunden( 1, 4711 );
    }
    catch ( Exception ex )
    {
        throw new SOGException(
           "Fehler bei Zugriff auf Tabelle Kunden Datensatz 1/4711", ex )
    }

Dies ermöglicht eine korrekte Fehleranalyse und schnelle Behebung.

Ableiten eigener Exceptionklassen


Leiten Sie zur Protokollierung von eigenen Fehlern eigene Exceptionklassen ab. Dies ermöglicht eine spezielle Reaktion auf genau diese Fehlersituation. Hier der vollständige Quellcode der SOGNoRecordException Klasse:


    public class SOGNoRecordException : SOGException
    {
        public SOGNoRecordException(): base () {}
        public SOGNoRecordException(String msg): base (msg) {}
        public SOGNoRecordException(String msg, Exception InnerException):
               base (msg,InnerException) {}
    }