Warnung! C ++ - Programmierer kommen hier mit möglicherweise unterschiedlichen Vorstellungen, wie die Ausnahmebehandlung durchgeführt werden sollte, um eine Frage zu beantworten, bei der es sich sicherlich um eine andere Sprache handelt!
Angesichts dieser Idee:
Stellen Sie sich zum Beispiel vor, wir haben eine Abrufressource, die eine HTTP-Anforderung ausführt und abgerufene Daten zurückgibt. Und anstatt von Fehlern wie ServiceTemporaryUnavailable oder RateLimitExceeded würden wir nur einen RetryableError auslösen, der dem Verbraucher vorschlägt, dass er die Anfrage nur wiederholen und sich nicht um bestimmte Fehler kümmern soll.
Ich würde vorschlagen, dass Sie die Bedenken, einen Fehler zu melden, mit Vorgehensweisen verwechseln, um darauf zu reagieren, die die Allgemeingültigkeit Ihres Codes beeinträchtigen oder viele "Übersetzungspunkte" für Ausnahmen erfordern .
Wenn ich beispielsweise eine Transaktion modelliere, bei der eine Datei geladen wird, kann dies aus mehreren Gründen fehlschlagen. Möglicherweise wird beim Laden der Datei ein Plugin geladen, das auf dem Computer des Benutzers nicht vorhanden ist. Möglicherweise ist die Datei einfach beschädigt, und beim Parsen ist ein Fehler aufgetreten.
Egal was passiert, sagen wir, die Vorgehensweise besteht darin, dem Benutzer zu melden, was passiert ist, und ihn aufzufordern, was er dagegen tun möchte ("erneut versuchen, eine andere Datei laden, abbrechen").
Werfer gegen Fänger
Diese Vorgehensweise gilt unabhängig davon, auf welche Art von Fehler wir in diesem Fall gestoßen sind. Es ist nicht in die allgemeine Idee eines Parsing-Fehlers eingebettet. Es ist nicht in die allgemeine Idee eingebettet, dass ein Plugin nicht geladen werden kann. Es ist eingebettet in die Idee, solche Fehler im genauen Kontext des Ladens einer Datei (der Kombination aus Laden einer Datei und Fehlschlagen) zu finden. Typischerweise sehe ich es grob gesagt als die catcher's
Verantwortung, die Vorgehensweise als Reaktion auf eine ausgelöste Ausnahme (z. B. Aufforderung des Benutzers mit Optionen) zu bestimmen, nicht die thrower's
.
Anders ausgedrückt, den Sites mit throw
Ausnahmen fehlen normalerweise solche Kontextinformationen, insbesondere wenn die auszulösenden Funktionen allgemein anwendbar sind. Selbst in einem völlig entarteten Kontext, in dem diese Informationen vorliegen, können Sie das Wiederherstellungsverhalten verbessern, indem Sie sie in die throw
Site einbetten . Die Sites, catch
die im Allgemeinen über die meisten verfügbaren Informationen verfügen, um eine Vorgehensweise zu bestimmen, und bieten Ihnen einen zentralen Ort zum Ändern, falls sich diese Vorgehensweise jemals für eine bestimmte Transaktion ändern sollte.
Wenn Sie versuchen, Ausnahmen auszulösen, die nicht mehr melden, was falsch ist, sondern ermitteln, was zu tun ist, kann dies die Allgemeingültigkeit und Flexibilität Ihres Codes beeinträchtigen. Ein Parsing-Fehler sollte nicht immer zu einer solchen Aufforderung führen. Er hängt vom Kontext ab, in dem eine solche Ausnahme ausgelöst wird (der Transaktion, unter der sie ausgelöst wurde).
Der blinde Werfer
Nur im Allgemeinen dreht sich ein Großteil des Designs für die Ausnahmebehandlung oft um die Idee eines blinden Werfers. Es weiß nicht, wie und wo die Ausnahme abgefangen wird. Gleiches gilt für noch ältere Formen der Fehlerbehebung mittels manueller Fehlerweitergabe. Websites, bei denen Fehler auftreten, enthalten keine Benutzeraktion. Sie enthalten nur die minimalen Informationen, um zu melden, welche Art von Fehler aufgetreten ist.
Umgekehrte Verantwortlichkeiten und Verallgemeinerung des Fängers
Beim genaueren Überlegen versuchte ich mir die Art von Codebasis vorzustellen, in der dies eine Versuchung werden könnte. Meiner Vorstellung nach (möglicherweise falsch) spielt Ihr Team hier immer noch die Rolle des "Verbrauchers" und implementiert auch den größten Teil des aufrufenden Codes. Möglicherweise gibt es viele unterschiedliche Transaktionen (viele try
Blöcke), bei denen alle dieselben Fehler auftreten können, und alle sollten aus Entwurfssicht zu einer einheitlichen Vorgehensweise für die Wiederherstellung führen.
Unter Berücksichtigung der Lightness Races in Orbit's
guten Antworten (die meiner Meinung nach von einer fortgeschrittenen bibliotheksorientierten Denkweise herrühren) könnten Sie immer noch versucht sein, Ausnahmen zu machen, die nur näher an der Transaktionswiederherstellungssite liegen.
Hier könnte es möglich sein, eine zwischengeschaltete, gemeinsame Transaktionsabwicklungs-Site zu finden, die die "was zu tun ist" -Anliegen tatsächlich zentralisiert, aber immer noch im Kontext des Fangens.
Dies gilt nur, wenn Sie eine Art allgemeine Funktion entwerfen können, die alle diese äußeren Transaktionen verwenden (z. B. eine Funktion, die eine andere aufzurufende Funktion eingibt, oder eine abstrakte Transaktionsbasisklasse mit überschreibbarem Verhalten, die diese zwischengeschaltete Transaktionssite modelliert, die das anspruchsvolle Abfangen ausführt ).
Dieser könnte jedoch dafür verantwortlich sein, die Vorgehensweise des Benutzers als Reaktion auf eine Vielzahl möglicher Fehler zu zentralisieren, und dies immer noch im Kontext des Fangens statt des Werfens. Einfaches Beispiel (Python-isch-Pseudocode, und ich bin nicht im geringsten ein erfahrener Python-Entwickler, daher könnte es eine idiomatischere Vorgehensweise geben):
def general_catcher(task):
try:
task()
except SomeError1:
# do some uniformly-designed recovery stuff here
except SomeError2:
# do some other uniformly-designed recovery stuff here
...
[Hoffentlich mit einem besseren Namen als general_catcher
]. In diesem Beispiel können Sie eine Funktion übergeben, die die auszuführende Aufgabe enthält, aber dennoch vom allgemeinen / einheitlichen Fangverhalten für alle Arten von Ausnahmen profitiert, an denen Sie interessiert sind, und den Teil "Was ist zu tun?" Weiterhin erweitern oder ändern Sie möchten von diesem zentralen Ort aus und dennoch in einem catch
Kontext, in dem dies normalerweise empfohlen wird. Das Beste von allem ist, dass wir die Wurfplätze davon abhalten können, sich mit der Frage zu befassen, was zu tun ist (unter Beibehaltung der Vorstellung des "blinden Werfers").
Wenn Sie keinen dieser Vorschläge hier hilfreich finden und die Versuchung groß ist, Ausnahmen zu machen, sollten Sie sich vor allem darüber im Klaren sein, dass dies zumindest sehr antiidiomatisch ist und möglicherweise eine verallgemeinerte Denkweise entmutigt.