Exception Practice
-
seldon schrieb:
"Fehler in der Programmlogik"
Danke für den Tipp. Bei meinen Beispielen allerdings scheint mir runtime_error durchaus angebracht. (Sockets, Dateien)
seldon schrieb:
Fehlercodes speichere ich ggf. natürlich als Zahl und nicht als String - das wär ja albern.
Nun ja, dann musst du aber auch alle Exceptions unterschiedlich fangen. Denn ansonsten könne man auch einfach eine Basisklasse fangen, und in den jeweiligen Spezialisierungen einen vollständigen Fehlerstring zusammenbasteln.
Das hälst du nicht für wünschenswert?
-
Ich versuche normal die möglichen Fehlerursachen in eigene Exceptions zu fassen und sie auch zu behandeln. Den String mit der Fehlermeldung kann ich dann in der Gui zusammenbauen. Etwas banales Beispiel, wenn ich eine Funktion aufrufe und weiß, sie kann eine IndexOutOfRange, eine DivisionByZero und eine InvalidParameter Exception schmeißen, dann kann ich an der Stelle wo ich sie aufrufe das auch abfangen, denn ich weiß normalerweise, woran das dann liegt, wenn so eine Exception kommt. Wenn ich den Fehler aber nicht im Griff habe, wird es etwas schwieriger. z.B. bei der Netzwerkkommunikation, wo 50 verschiedene Fehler kommen können. Dann reicht es aber vielleicht ersteinmal eine entsprechende NetworkCommunicationException zu schmeißen und dann weiß man, ok, bei der Kommunikation ist was schiefgelaufen und dann evtl. weiter nachforschen, z.b. über den Fehlercode, um dem Benutzer eine aussagekräftige Fehlermeldung (wie Passwort falsch oder Server nicht erreichbar) anzuzeigen.
-
cooky451 schrieb:
seldon schrieb:
Fehlercodes speichere ich ggf. natürlich als Zahl und nicht als String - das wär ja albern.
Nun ja, dann musst du aber auch alle Exceptions unterschiedlich fangen. Denn ansonsten könne man auch einfach eine Basisklasse fangen, und in den jeweiligen Spezialisierungen einen vollständigen Fehlerstring zusammenbasteln.
Die what()-Methode gibt's ja nach wie vor, und wenn ich den Fehlercode direkt brauche, kann ich mit std::exception eh nichts anfangen. Ich meine das etwa so:
// Für diese Dinge benutze ich dann gerne X-Makros, um mir keine Gedanken // um die Synchronisation zwsichen Fehlercode und Fehlermeldung machen zu müssen. enum error_code { ERR_SUCCESS, ERR_FEHLER1, ERR_FEHLER2, ... }; extern char const *const error_messages[]; // Hier nicht von std::logic_error, weil kein std::string gebraucht wird, um // die Fehlermeldung aufzubewahren. class my_exception : public std::exception { public: my_exception(error_code ecode) : ecode_(ecode) { } virtual ~my_exception() throw() { } virtual error_code code() const throw() { return ecode_; } virtual char const *what() const throw() { return error_messages[ecode_; } private: error_code ecode_; };Natürlich ist es eine andere (und nicht triviale) Frage, wann man Fehlercodes benutzen und wann man neue Exceptionklassen einführen sollte; die kann ich aber nicht pauschal beantworten.
-
Mechanics schrieb:
wie Passwort falsch oder Server nicht erreichbar
Warum sollte das eine Exception werfen? Solche erwarteten Fehler werden bei mir ohne Exceptions behandelt.
-
Das leidige Thema. Such doch einfach im Forum.
-
nostdexcept schrieb:
Mechanics schrieb:
wie Passwort falsch oder Server nicht erreichbar
Warum sollte das eine Exception werfen? Solche erwarteten Fehler werden bei mir ohne Exceptions behandelt.
Wo? Wenn es eine interne Funktion gibt, die irgendwas übers Netzwerk übertragen muss, hat sie keine "erwarteten Fehler" zu behandeln. Wenn die Netzwerkkommunikation nicht funktioniert hat, dann ist es eine Ausnahme von dem erwarteten Verhalten der Funktion und wird durch eine Exception weitergegeben. Behandeln könnte man sie dann z.B. in der GUI.
-
Das erwartete Verhalten wird vom Device bestimmt und nicht vom Programmierer. Der Abbruch einer Netzwerkverbindung ist sehr wahrscheinlich.
-
knivil schrieb:
Das erwartete Verhalten wird vom Device bestimmt und nicht vom Programmierer. Der Abbruch einer Netzwerkverbindung ist sehr wahrscheinlich.
Das ist keine Antwort. Die Frage ist, wo was behandelt wird. Exceptions sind eine Möglichkeit, Fehler zu behandeln. Die Funktion selbst sollte sie nicht behandeln, das wär ganz schlechtes Design. Die Fehler müssen nach oben gegeben werden. Viel mehr Möglichkeiten als return codes oder Exceptions gibts nicht. Bevor ich return codes verwende, verwende ich doch viel lieber Exceptions.
-
Habt ihr alle C++11 verpasst? std::error_code, std::error_category, std::error_condition, std::system_error etc? Da stellt sich überhaupt nicht frage was man mit Errorcodes macht, da die Best-Practise praktisch vorgegeben ist.
-
Das ist keine Antwort.
Nein, ich sage nur, dass deine Argumentation scheisse ist.
Die Funktion selbst sollte sie nicht behandeln, das wär ganz schlechtes Design.
Hast du deinen Doktor in Design gemacht? Du bist voreingenommen und kann wie alles nicht pauschal beantwortet werden. Aber vielleicht kann ja jemand ein gutes Buch zum Thema empfehlen. Persoenlich wuerde mich interessieren, wie sich Exceptions mit Multithreading verhalten.