Problem mit Exceptions



  • Hallo!

    Ich habe hier einige Klassen mit Methonden, die irgendwelche Aufgaben leisten.
    Komm ich nun in einer solchen Methode an einen Punkt, an dem etwas unstimmig ist, wird eine Exception vom selbstdef. Typ "StatusError" geworfen.

    void Klassenname::MethodeSoUndSo(){
       //tu hier irgendwas
       if(status == false)
          throw StatusError(IntVariable);
    }
    

    Zudem habe ich eine ganze konkrete Forderung, wie StatusError aussehen soll:

    Bei jedem Auftreten eines Fehlers soll automatisch ein Protokolleintrag in eine Log-Datei ERROR.LOG geschrieben werden.  
    "Automatisch" heißt dabei: 
    - Das Hauptprogramm ist an dem Log-Eintrag überhaupt nicht beteiligt. Dieser Eintrag erfolgt z.B. auch dann, 
    wenn keinerlei Exception Handling im Hauptprogramm erfolgt. 
    - Die Klassen sollen unabhängig von der konkreten Fehlerreaktion sein.
     Deshalb sind sie am Dateiprotokoll ebenso wenig beteiligt wie sie den Fehler auch nicht selbst an der Konsole melden.
     Daraus folgt, dass die Dateiausgabe (ebenso wie die Generierung des Fehlertextes) von der Exception-Klasse abgewickelt werde muss
    

    Die Klasse StatusError habe ich so realisiert:

    class StatusError{
    	private:
    		string message;
    	public:
    		StatusError(int sig){
    			ostringstream os;
    			os << "Fehler beim Leihen / Rueckgeben von Signature " << sig <<".";
    			message = os.str();
    
    			ofstream f("ERROR.LOG",ios::out | ios::app);
    			f << message << "\n";
    		}
    		string ausgabe(){return message;}
    };
    

    Mein Problem ist: Wenn ich in meinem Hauptprogramm keinen Handler anlege und die Exception wird geworfen, bekomm ich einen Fehler:

    Unhandled exception at 0x7c812a5b in Medienbib4.exe: Microsoft C++ exception: StatusError at memory location 0x0012fc60
    

    Die Aufgabenstellung sagt aber ganz klar: Selbst wenn ich keine try- und catch-Blöcke im Hauptprogramm habe, soll der Logeintrag erfolgen.
    Weiß jemand Rat?



  • Das Objekt, was dann geworfen wird (StatusError), wird ja auch dann konstruiert - und da du im CTor in die Log-Datei schreiben lässt, solltest du die Aufgabenstellung auch erfüllt haben!

    Ich würde nur

    f << message << "\n";
    

    in

    f << message << std::endl;
    

    ändern...

    bb



  • Gibts denn keine Möglichkeit den Fehler so zu unterdrücken, dass der Programmablauf im Weiteren nicht gestört wird?



  • lebkuchenmann schrieb:

    Gibts denn keine Möglichkeit den Fehler so zu unterdrücken, dass der Programmablauf im Weiteren nicht gestört wird?

    Nein. Das wäre auch nicht der Sinn von Exceptions - wenn sie einfach ignoriert werden können, sinds auch keine ausnahmen...

    Das verlangt deine Aufgabenstellung doch aber auch gar nicht:

    Bei jedem Auftreten eines Fehlers soll automatisch ein Protokolleintrag in eine Log-Datei ERROR.LOG geschrieben werden.

    haben wir

    "Automatisch" heißt dabei:
    - Das Hauptprogramm ist an dem Log-Eintrag überhaupt nicht beteiligt.

    haben wir

    Dieser Eintrag erfolgt z.B. auch dann, wenn keinerlei Exception Handling im Hauptprogramm erfolgt.

    haben wir

    - Die Klassen sollen unabhängig von der konkreten Fehlerreaktion sein.
    Deshalb sind sie am Dateiprotokoll ebenso wenig beteiligt wie sie den Fehler auch nicht selbst an der Konsole melden.
    Daraus folgt, dass die Dateiausgabe (ebenso wie die Generierung des Fehlertextes) von der Exception-Klasse abgewickelt werde muss

    und auch das haben wir

    bb



  • lebkuchenmann schrieb:

    Gibts denn keine Möglichkeit den Fehler so zu unterdrücken, dass der Programmablauf im Weiteren nicht gestört wird?

    Doch, in dem du die exception catchst.

    try {
       mach_was_boeses();
    } catch( const Error& e ) {
       behandle_angerichtetes_uebel();
    }
    

    Sollte aber in deinem $KOMPENDIUM zu exceptions stehen...



  • Damit unterdrückt man den Fehler aber nicht...



  • Wenn der Programmablauf "im Weiteren nicht gestört" gestört werden soll, dann darfst du auch keine Exception werfen. Stattdessen schreibst du StatusError(IntVariable); und damit läuft das Programm trotz Fehler weiter. Inwiefern das sinnvoll sein soll, kann ich aber nicht nachvollziehen.



  • unskilled schrieb:

    Damit unterdrückt man den Fehler aber nicht...

    Sry, aber es werden Exceptions geworfen. Ob das seine eigenen Klassen sind oder nicht, es ist scheinbar einfach so.
    Dann gibts die Beschwerde, dass das Programm abbricht. Was ja auch passieren SOLL wenn die Exception nicht abgefangen wird. Einen Weg, die Exceptions zu umgehen ohne try/catch gibt es nicht.

    Also entweder

    1. Keine Exceptions werfen
    2. Keinen Programmabbruch haben wollen -> try/catch
    3. Programmabbruch in Kauf nehmen (unschön)
    4. Das Programm per exit beenden, wenn ein Fehler auftritt -> try/catch.

    Und das sollte auch im Buch/Tutorial/sonstwas bei den Exceptions stehen.

    Unterdrücken geht nicht.



  • tandem schrieb:

    1. Keine Exceptions werfen
    2. Keinen Programmabbruch haben wollen -> try/catch
    3. Programmabbruch in Kauf nehmen (unschön)
    4. Das Programm per exit beenden, wenn ein Fehler auftritt -> try/catch.

    Wenn man 2) nur dazu benutzt, einen Programmabbruch zu verhindern, indem man Exceptions ignoriert, finde ich 3) immer noch schöner. Exceptions werden nicht ausgelöst, um den Programmierer zu nerven.

    1. ist übrigens auch keine gute Idee, da das Programm mit exit() abrupt beendet wird und keine Destruktoren mehr aufgerufen werden.

Anmelden zum Antworten