richtige fehlerbehandlung



  • Guten Tag,

    ich habe eine Klasse die Operationen an der Windows-Registry erlaubt.
    Das momentane Problem ist, eine geeignete Fehlerbehandlung zu implementieren.

    So wie ich das sehe habe ich folgende Möglichkeiten:

    1. Exceptions

    Wenn ein Fehler auftritt, werfe ich eine Exception vom Typ std::runtime_error.
    Finde ich persönlich aber nicht so gut, kann es aber nicht begründen, da ich mich damit noch nicht wirklich gut auskenne. Meine Klasse arbeitet nach dem RAII-Prinzip, wird, wenn die Exception geworfen wird dann mein Objekt zerstört und der Destruktor aufgerufen, oder habe ich dann ein Ressourcenleck?

    1. Fehlermeldung durch Rückgabewerte

    Ich gebe einen bestimmten Fehlercode zurück wenn ein Fehler auftritt. Nur haben meine Funktionen teilweise unterschiedliche Rückgabetypen, finde ich umständlich und nicht gut zu benutzen.

    1. Fehlerfunktion

    Das finde ich momentan am besten. Ich implementiere eine Memberfunktion error() die, ähnlich wie bei den Streams, einfach nur true/false zurückgibt, also ob ein Fehler aufgetreten ist oder nicht.

    Könnt Ihr mir Tipps geben wie man das am besten lösen könnte / welche möglichen Lösungen ich noch nicht kenne?



  • Gib eine Referenz auf einen std::error_code mit, oder wirf eine std::system_error Exception. (Vielleicht kann man das einstellen? Vielleicht gibst du einen Pointer auf einen std::error_code mit?)
    Siehe auch http://blog.think-async.com/2010/04/system-error-support-in-c0x-part-5.html
    Ich muss sagen, in letzter Zeit immer mehr Abstand von Exceptions genommen zu haben. Eigentlich werfe ich nur noch genau dann Exceptions, wenn ich den Fehler nicht behandeln will/kann, sondern nur anzeigen möchte.

    Ein Ressourcenleck bekommst du allerdings nicht dadurch. Wenn eine Exception geworfen wird, werden alle vorher konstruierten Objekte ordnungsgemäß abgeräumt (ihre Destruktoren werden aufgerufen), bis die Exception wieder gefangen wird. Das ist auch der Grund dafür warum man keine Exception aus Destruktoren werfen soll - mit zwei gleichzeitig fliegenden Exceptions kann C++ (noch?) nichts anfangen.

    Die Fehlerfunktion (dann bitte auch mir std::error_code) wäre natürlich auch möglich. Prinzipiell bin ich da eher abgeneigt, aber ein wirklich gutes, handfestes Argument dagegen habe ich nicht. Vergessen kann man Fehlerbehandlung immer - auch mit Exceptions - und Multithreading ist bei deiner Klasse wohl eh nicht vorgesehen.



  • Ok vielen Dank, das hat mir schon sehr weitergeholfen.

    Noch eine etwas (dumme) Frage:

    Ich habe jetzt einen privaten Member

    std::system_error _ec
    

    und diese Funktion:

    std::string& Registry::error()
    {
    	return _ec.message();
    }
    

    Ich gebe ja eine Referenz auf einen std::string zurück, ist das jetzt undefiniertes Verhalten? Ich denke schon, oder? Immerhin erstelle ich mit _ec.message() eine lokale Variable die daraufhin wieder zerstört wird? Bin nur etwas verwirrt, weil das Objekt _ec ja weiterhin vorhanden ist.



  • Ja, das ist UB, wozu überhaupt eine Referenz? Der String wird da eh gemoved. Abgesehen davon ist es doch mehr als ungeschickt, da einen String zurückzugeben. Warum nicht std::error_code? 😕



  • Das war nur ein Beispiel, hatte mich das gerade irgendwie gefragt 😉
    Ich denke ich werde das jetzt so machen wie bei dem Link den du mir geschickt hast 🙂


Anmelden zum Antworten