try catch in jeder funktion?
-
Bisher hatte ich noch das Glück, nicht unter Zeitdruck zu stehen (mal sehen, was die Zukunft bringt). Aber selbst wenn die Debug-Phase erst beim Kunden stattfindet, sollte nach einer Exception nicht einfach weitergemacht werden, als sei nichts passiert - entweder das Programm weiß selber, wie es auf einen Fehler reagieren kann oder es verabschiedet sich mit einer Information für den Anwender und/oder Entwickler (notfalls meldet es auch nur einen Fehler und setzt sich auf den letzten verwertbaren Status zurück).
-
Wir reden nicht über Freeware. Der Kunde haut dich, wenn das Programm crasht. Egal ob 1x oder alle 10 min.
Egal... Wir waren ja bei try/catch
Wegen der Performance hatte ich gelesen, dass es da keine Probleme gibt. Und wegen dem weiterlaufen - hmmmmmm naja, lööft halt erstmal. Nach mir die ....
-
es gibt keine geschwindgikeitsunterschiede, wenn du keine exceptions benutzt, aber dein programm mit solchen kompiliert hast. wenn du sie einbaust, aber nie wirfst, ist der unterschied minimal. wenn du sie allerdings wirfst, sind sie eher von der langsamen art.
was deine einstellung zum weiterlaufen angeht: ich wünsche dir viel spaß mit den fehlermeldungen deiner kunden, die dann plötzlich nicht reproduzierbar sind. das stört die kunden gemeinhin noch weit mehr als reproduzierbare abstürze, an die man sich gewöhnen kann...
-
Also wenn es nur um die Information geht, ob eine Funktion mittels exception oder return beendet wurde, würde ich einfach eine "Scopeklasse" stricken:
struct ErrorLogger { bool err; string fktName; ErrorLogger(string const& name) : err(true), fktName(name) {} void clear() { err = false; } ~ErrorLogger() { if(err) writelog("Fehler in " + fktName); } }; void blub { ErrorLogger el("blub"); ..nur hier code! el.clear(); }Damit hat man eine zentrale Stelle für das Logging (die man auch zentral konfigurieren kann) und hat auch keine "Copy-Paste-Probleme" - einzig das Vergessen eines clear()-Calls kann einen erwischen ... aber das fällt schon im Gutfall-Test schnell auf.
KANN man machen (haben wir in Teilen unseres Programms auch)....Gruß,
Simon2.
-
CStoll schrieb:
Bisher hatte ich noch das Glück, nicht unter Zeitdruck zu stehen (mal sehen, was die Zukunft bringt). Aber selbst wenn die Debug-Phase erst beim Kunden stattfindet, sollte nach einer Exception nicht einfach weitergemacht werden, als sei nichts passiert - entweder das Programm weiß selber, wie es auf einen Fehler reagieren kann oder es verabschiedet sich mit einer Information für den Anwender und/oder Entwickler (notfalls meldet es auch nur einen Fehler und setzt sich auf den letzten verwertbaren Status zurück).
Theoretisch ja. Aber bei manchen Plugin- oder Serveranwendungen ist es nicht immer so einfach eine Fehlermeldung irgendwo anzuzeigen. Und wenn bei einer Präsentation eine "Windows Fehlermeldung" kommt und sich das Programm verabschiedet, dann kommt das glaub ich um einiges schlechter, als eine Funktion die nichts macht, vorallem bei Programmen die eine Weile zum starten brauchen oder man eine ganze Weile arbeiten musste, bis man zu dieser Stelle kommt. Da ist es dem Kunden dann lieber, wenn das Plugin so "stabil" läuft, dass er seine Arbeit noch speichern und sich dann beschweren kann, als das seine Arbeit auf einen Schlag weg ist. Sowas sieht für den Kunden halt stabiler aus, als eine Anwendung die sich dauernd verabschiedet. Natürlich sollte man nicht überall alle exceptions fangen und dann planlos versuchen weiterzumachen. Am besten sollte man sie so platzieren, dass das Programm dann wieder in einem vernünftigen Zustand ist, was sicher nicht immer geht.
-
xyz123 schrieb:
Wir reden nicht über Freeware. Der Kunde haut dich, wenn das Programm crasht. Egal ob 1x oder alle 10 min.
Deswegen sagte ich ja auch etwas von "auf letzten verwertbaren Status zurücksetzen"- wenn du nach dem Fehler einfach weitermachst, als wäre nichts passiert, ist das noch ärgerlicher als eine Nachricht "hier ist was kaputt" (vor allem wegen der möglichen Folgefehler).
Edit @Kenner: Sagte ich doch - man sollte dort auf einen Fehler reagieren, wo man damit umgehen kann. (und ein Teil-Reset der Anwendung auf den Zustand vor dem Fehler kann auch noch als "umgehen" durchgehen)
-
Schade, dass ich die Sache jetzt so verteidige. Mags eigentlich auch überhaupt nicht - bin da halt aber so reingerutscht.

Noch mal kurz. Ich sagte nie, dass das Programm alle paar Sekunden eine Exception wirft. Überhaupt nicht. (Ich auch können C++
)
Es geht einfach nur darum wie ihr es findet auf diese Art und Weise Fehler abzufangen, auch wenn sie nur einmal im Monat auftreten. Oder Woche, was auch immer. Nicht! ständig...
-
LordJaxom schrieb:
Unsere VB-Funktionen beginnen auch grundsätzlich mit on error goto bzw. in neueren Programmen Try...Catch
Das solltest Du schleunigst ändern. Auch in VB6 war sowas meist schon großer Quatsch und unter .NET ist es das definitiv.
-
Konrad Rudolph schrieb:
LordJaxom schrieb:
Unsere VB-Funktionen beginnen auch grundsätzlich mit on error goto bzw. in neueren Programmen Try...Catch
Das solltest Du schleunigst ändern. Auch in VB6 war sowas meist schon großer Quatsch und unter .NET ist es das definitiv.
Mache ich. Bei jeder Funktion die ich anfasse, fliegt als erstens dieses Errorhandling raus. Ansonsten unbehandelte oder unbehandelbare Exceptions werden dann nur noch auf der GUI-Ebene gefangen, wenn möglich behandelt und wenn nötig das Programm dann beendet.
Leider bin ich nicht der einzige im Team. Und viele (auch bzw. gerade der älteren Verantwortlichen) stehen auf dem Beamtenstandpunkt "des hammer immer scho gmacht"

-
LordJaxom schrieb:
"des hammer immer scho gmacht"

müsste es nicht "des ham mer immer scho gmacht" heißen? Hat doch nix mit nem hammer zu tun, sondern "haben wir(mir)"
-
sprache schrieb:
LordJaxom schrieb:
"des hammer immer scho gmacht"

müsste es nicht "des ham mer immer scho gmacht" heißen? Hat doch nix mit nem hammer zu tun, sondern "haben wir(mir)"
Wenn, dann bitte gleich ganz korrekt, ja? „Ha’m mer immer scho’ g’macht,“ (oder heißt es gar „Ha’m ’er“?). – Aber das ist doch sowas von egal.
-
Dann sind wir jetzt durch?
Oder hat noch jemand was konstruktives?
-
CStoll schrieb:
Exceptions stehen für Ausnahmesituationen, die durch falsche Bedienung oder Systemstörungen auftreten können - und normalerweise sollte der Programmierer vor der Auslieferung wissen, wo solche Störungen auftreten können und wie er auf sie reagieren kann. Bugs solltest du beheben, während du in der Debug-Phase bist.
Veto
Da man als Programmierer fuer Software, die von anderen als einem selbst benutzt werden soll, immer von DAUs ausgehen muss, sollten Bedienfehler keine Ausnahmen ausloesen sondern durch hinreichende Tests der Eingabe abgefangen werden. Sprich: sobald dem User irgendeine Art der Eingabe und des Eingriffs in den Programmablauf gestattet wird, sofort misstrauisch pruefen, was er gemacht hat, bevor mans ans eigentliche Programm weitergibt. (MVC ist praedestiniert dafuer). Ausnahmen sollten wirklich Ausnahmen bleiben, und dass ein User sich bloed anstellt ist nunmal keine Ausnahme 
Solche Fehleingaben sind das, was der Programmierer vor der Auslieferung vorhersehen kann und deren Auswirkungen er von vornherein verhindern muss. Ausnahmen sind Sicherheitsmechanismen, der doppelte Boden fuer Dinge, die eigentlich nicht passieren koennen, wo man aber doch so vorsichtig sein moechte, es zur Not abzufangen (z.B. wenn die Daten im Netzwerkkabel aus der Kurve fliegen)Punkte, die keine Ausnahme sein sollten:
- der User moechte eine Datei oeffnen, die nicht existiert.
- der User gibt Buchstaben bei seinem Geburtsdatum an
- ein Eintrag der Config-Datei ist fehlerhaft (Warnung ausgeben reicht)Punkte, die Ausnahmen sein koennen:
- Die Datei, die das Programm gerade eben selbst angelegt hat, exisitiert nichtmehr
- wichtige Daten sind von "irgendwem" ueberschrieben worden (kann eigentlich nicht passieren, so schusselig ist man als Programmierer doch nicht, oder?)
- unvorhersehbare Hardwareausfaelle (im pragmatic programmer wird das Beispiel "Ratten zernagen die Netzwerkkabel" angefuehrt, auch wenns das meines Erachtens nicht ganz trifft.)Strittige Punkte sind beispielsweise:
- Speicher oder Festplatte voll
- Abbruch der Netzwerkverbindung (meiner Erfahrung nach keine Ausnahme)
-
pumuckl schrieb:
Punkte, die keine Ausnahme sein sollten:
- der User moechte eine Datei oeffnen, die nicht existiert.Und das ist eben genau falsch. In dieser Situation hat man gar keine andere Wahl, als mit einer Ausnahme zu reagieren denn es könnte gut sein, dass der Benutzer sehr wohl eine existente Datei ausgewählt hat, die aber zwischen der Auswahl und dem Überprüfen auf Existenz (selbst, wenn das direkt hintereinander erfolgt) gelöscht worden ist oder das Trägermedium entfernt wurde.
Merke: *Jede* Interaktion mit einem nicht-synchronisierten System (eben z.B. Dateisystem, Hardware, Netzwerk) benötigt eine Ausnahmebehandlung, denn anders kann man darauf gar nicht reagieren: Im Zweifelsfall sind das nämlich schwere Ausnahmefehler. Daher sind Deine folgenden „strittigen“ Punkte auch alles andere als strittig, sondern glasklare Fälle, in denen man Ausnahmen braucht.
-
pumuckl schrieb:
...
Punkte, die keine Ausnahme sein sollten:
...
Punkte, die Ausnahmen sein koennen:
...
Strittige Punkte sind beispielsweise:
...Hmmm - ich weiß nicht.
Das ist sehr stark "Konvention".
Für mich ist eine exception dann das Mittel der Wahl, wenn eine Funktion ihre fachliche Aufgabe nicht erfüllen konnte und das dem Aufrufer mitteilen will.
Das bedeutet natürlich auch, dass eine Funktion "sucheEintraege()" KEINE exception wirft, wenn sie keinen gefunden hat - weil "kein Eintrag" ein fachlich definierter Zustand ist.
Das setzt allerdings eine saubere fachliche Modellierung voraus, in denen wirklich alle Fälle (auch die "Ausnahme-/Fehlerfälle") abgedeckt sind und leider ist sowas eher selten. Ich bekomm' immer die Krise wenn in einer fachlichen Beschreibung nur steht: "Der Wert ist zu bestimmen".
Sagen wir mal so: Immer wenn man in Versuchung steht, einen Fehlercode via return oder in einen Parameter codiert zurückzugeben, würde ich eine exception vorziehen.
(Ausnahmen bestätigen wie immer die Regel)
Gruß,
Simon2.
-
Konrad Rudolph schrieb:
pumuckl schrieb:
Punkte, die keine Ausnahme sein sollten:
- der User moechte eine Datei oeffnen, die nicht existiert.Und das ist eben genau falsch. In dieser Situation hat man gar keine andere Wahl, als mit einer Ausnahme zu reagieren denn es könnte gut sein, dass der Benutzer sehr wohl eine existente Datei ausgewählt hat, die aber zwischen der Auswahl und dem Überprüfen auf Existenz (selbst, wenn das direkt hintereinander erfolgt) gelöscht worden ist oder das Trägermedium entfernt wurde.
Man prüft auch nicht auf Existenz und öffnet dann, sondern man öffnet und prüft, ob das geklappt hat. Da man hier davon ausgehen muss, dass die Datei nicht existiert, ist das keine Ausnahme, sondern regulärer Kontrollfluss.
-
Simon2 schrieb:
Für mich ist eine exception dann das Mittel der Wahl, wenn eine Funktion ihre fachliche Aufgabe nicht erfüllen konnte und das dem Aufrufer mitteilen will.
Das bedeutet natürlich auch, dass eine Funktion "sucheEintraege()" KEINE exception wirft, wenn sie keinen gefunden hat - weil "kein Eintrag" ein fachlich definierter Zustand ist.Sagen wir mal so: Immer wenn man in Versuchung steht, einen Fehlercode via return oder in einen Parameter codiert zurückzugeben, würde ich eine exception vorziehen.
Öhm, wäre das Ergebnis "kein Eintrag" nicht eine Art Fehlercode? Wo ziehst du denn da die Trennlinie?
(Ausnahmen bestätigen wie immer die Regel)
Aber nur, wenn sie gefangen werden

-
Bashar schrieb:
...
Öhm, wäre das Ergebnis "kein Eintrag" nicht eine Art Fehlercode? Wo ziehst du denn da die Trennlinie?...Hier ist das einfach fachlich zu modellieren: Die leere Ergebnismenge ist erlaubt.
std::string::length() gibt auch problemlos 0 zurück...Natürlich ist das nicht immer ganz eindeutig - aber deswegen ist es ja auch eher "Richtlinie" und kein "Gesetz".
Gruß,
Simon2.
-
Bashar schrieb:
Man prüft auch nicht auf Existenz und öffnet dann, sondern man öffnet und prüft, ob das geklappt hat. Da man hier davon ausgehen muss, dass die Datei nicht existiert, ist das keine Ausnahme, sondern regulärer Kontrollfluss.
Wenn die Datei nicht existiert, kann die Funktion ihre reguläre Arbeit (Daten lesen und verarbeiten) nicht erledigen, ergo gibt es einen Fehler.
(und auch erwartete Fehlerzustände sind immer noch Fehler, die den regulären Ablauf beeinflussen - das muß nicht immer in einer Exception enden, aber es kann)
-
Bashar schrieb:
Man prüft auch nicht auf Existenz und öffnet dann, sondern man öffnet und prüft, ob das geklappt hat. Da man hier davon ausgehen muss, dass die Datei nicht existiert, ist das keine Ausnahme, sondern regulärer Kontrollfluss.
it depends. wenn ich mich in einer routine befinde, die bspw nur zum speichern da ist, so ist in dieser routine nichts gegen den fehler machbar (also werfe ich etwas oder lass die von fstream erzeugte exception einfach durch) und die übergeordnete methode kann dann eine sinnvolle fehlermeldung und -behandlung liefern.