Ich halte es einfach.
Eine Bibliothek hat einen Basis-Ausnahmetyp, der von std ::: runtime_error erweitert wurde (das gilt von C ++ aus entsprechend für andere Sprachen). Diese Ausnahme benötigt eine Nachrichtenzeichenfolge, damit wir protokollieren können. Jeder Wurfpunkt hat eine eindeutige Nachricht (normalerweise mit einer eindeutigen ID).
Das ist alles.
Hinweis 1 : In Situationen, in denen jemand, der die Ausnahme abfängt, die Ausnahmen beheben und die Aktion neu starten kann. Ich werde abgeleitete Ausnahmen für Dinge hinzufügen, die möglicherweise eindeutig an einem entfernten Ort behoben werden können. Dies ist jedoch sehr, sehr selten (Denken Sie daran, dass der Fänger wahrscheinlich nicht in der Nähe des Wurfpunkts ist, sodass die Behebung des Problems schwierig sein wird (aber alles ist situationsabhängig)).
Anmerkung 2 : Manchmal ist die Bibliothek so einfach, dass es sich nicht lohnt, ihr eine eigene Ausnahme zu geben, und std :: runtime_error wird dies tun. Es ist nur wichtig, eine Ausnahme zu haben, wenn die Fähigkeit, sie von std :: runtime_error zu unterscheiden, dem Benutzer genügend Informationen geben kann, um etwas damit zu tun.
Anmerkung 3 : Innerhalb einer Klasse bevorzuge ich normalerweise Fehlercodes (diese werden jedoch in der öffentlichen API meiner Klasse niemals ausgeblendet).
Betrachten Sie Ihre Kompromisse:
Die Kompromisse, die ich sehe, umfassen:
Weitere Ausnahmeklassen können für API-Benutzer eine sehr genaue Fehlerbehandlung ermöglichen (anfällig für Benutzerkonfigurations- oder Datenfehler oder nicht gefundene Dateien).
Ermöglichen Ihnen mehr Ausnahmen wirklich eine feinere Getreidesteuerung? Die Frage wird, ob der abfangende Code den Fehler wirklich anhand der Ausnahme beheben kann. Ich bin sicher, dass es solche Situationen gibt und in diesen Fällen sollten Sie eine weitere Ausnahme haben. Alle Ausnahmen, die Sie oben aufgeführt haben, sind jedoch die Generierung einer großen Warnung und das Stoppen der Anwendung.
Weitere Ausnahmeklassen ermöglichen, dass fehlerspezifische Informationen in die Ausnahme eingebettet werden und nicht nur eine Zeichenfolgemeldung oder ein Fehlercode
Dies ist ein guter Grund für die Verwendung von Ausnahmen. Die Informationen müssen jedoch für die Person nützlich sein, die sie zwischenspeichert. Können sie die Informationen verwenden, um Korrekturmaßnahmen durchzuführen? Wenn sich das Objekt in Ihrer Bibliothek befindet und nicht zur Beeinflussung der API verwendet werden kann, sind die Informationen unbrauchbar. Sie müssen sehr genau festlegen, dass die ausgelesenen Informationen für die Person, die sie abfangen kann, einen nützlichen Wert haben. Die Person, die es abfängt, befindet sich normalerweise außerhalb Ihrer öffentlichen API. Passen Sie daher Ihre Informationen so an, dass sie mit den Dingen in Ihrer öffentlichen API verwendet werden können.
Wenn sie nur die Ausnahme protokollieren können, ist es am besten, statt vieler Daten nur eine Fehlermeldung auszugeben. Da der Fänger in der Regel eine Fehlermeldung mit den Daten aufbaut. Wenn Sie die Fehlermeldung erstellen, ist sie für alle Catcher konsistent. Wenn Sie dem Catcher ermöglichen, die Fehlermeldung zu erstellen, wird derselbe Fehler möglicherweise unterschiedlich gemeldet, je nachdem, wer anruft und abfängt.
Weniger Ausnahmen, aber Einbettung eines Fehlercodes, der als Suche verwendet werden kann
Sie müssen feststellen, ob der Fehlercode sinnvoll verwendet werden kann. Wenn dies möglich ist, sollten Sie eine eigene Ausnahme haben. Andernfalls müssen Ihre Benutzer jetzt switch-Anweisungen in catch implementieren (was den ganzen Punkt zunichte macht, wenn catch automatisch mit Dingen umgeht).
Wenn dies nicht möglich ist, verwenden Sie in der Ausnahme eine Fehlermeldung (Sie müssen den Code nicht aufteilen, und die Meldung macht es schwierig, nachzuschlagen).
Fehlercodes und Flags direkt von Funktionen zurückgeben (manchmal nicht möglich von Threads)
Das Zurückgeben von Fehlercodes ist intern großartig. Es ermöglicht Ihnen, Fehler dort und dann zu beheben, und Sie müssen sicherstellen, dass Sie alle Fehlercodes beheben und diese berücksichtigen. Es ist jedoch eine schlechte Idee, sie über Ihre öffentliche API zu verbreiten. Das Problem ist, dass Programmierer häufig vergessen, nach Fehlerzuständen zu suchen (zumindest mit einer Ausnahme, wird ein ungeprüfter Fehler die Anwendung zwingen, einen nicht behandelten Fehler zu beenden, wodurch im Allgemeinen alle Ihre Daten beschädigt werden).
Implementierung eines Ereignis- oder Rückrufsystems bei einem Fehler (vermeidet das Abwickeln des Stapels)
Diese Methode wird häufig in Verbindung mit anderen Fehlerbehandlungsmechanismen verwendet (nicht als Alternative). Denken Sie an Ihr Windows-Programm. Ein Benutzer leitet eine Aktion ein, indem er einen Menüpunkt auswählt. Dadurch wird eine Aktion in der Ereigniswarteschlange generiert. Die Ereigniswarteschlange weist schließlich einen Thread zu, der die Aktion handhabt. Der Thread soll die Aktion ausführen und schließlich zum Thread-Pool zurückkehren und auf eine weitere Aufgabe warten. Hier muss eine Ausnahme an der Basis von dem mit dem Job beauftragten Thread abgefangen werden. Das Ergebnis des Erfassens der Ausnahme führt normalerweise dazu, dass ein Ereignis für die Hauptschleife generiert wird, das schließlich dazu führt, dass dem Benutzer eine Fehlermeldung angezeigt wird.
Aber es sei denn, Sie können trotz der Ausnahme weitermachen, der Stapel wird sich abwickeln (zumindest für den Thread).