Best Practice-Methode, um anzugeben, dass eine Serveranforderung fehlgeschlagen ist?

8

Ich schreibe eine API, die eine Verbindung zu einem Dienst herstellt, der entweder eine einfache "Erfolg" -Nachricht oder eine von mehr als 100 verschiedenen Fehlern zurückgibt.

Ursprünglich dachte ich, ich schreibe die Methode, die eine Anfrage an diesen Dienst sendet. Wenn die Methode erfolgreich ist, gibt sie nichts zurück, aber wenn sie aus irgendeinem Grund fehlschlägt, löst sie eine Ausnahme aus.

Ich habe diesen Entwurf nicht sehr gemocht, aber auf der anderen Seite las ich gerade Joshua Blochs " Wie man eine gute API gestaltet und warum es wichtig ist ", wo er sagt" Exceptions auslösen, um außergewöhnliche Bedingungen anzuzeigen ... Erzwinge dem Client nicht, Ausnahmen für den Kontrollfluss zu verwenden. " (Und umgekehrt, versage nicht leise.)

Andererseits habe ich bemerkt, dass die von mir verwendete HttpWebRequest eine Ausnahme auszulösen scheint, wenn die Anfrage fehlschlägt, anstatt eine Antwort mit einer "500 Internal Server Error" Nachricht zurückzugeben.

Was ist das beste Muster für das Melden von Fehlern in diesem Fall? Wenn ich bei jeder fehlgeschlagenen Anfrage eine Ausnahme mache, habe ich irgendwann massive Schmerzen?

Bearbeiten: Vielen Dank für die Antworten bisher. Einige Ausführungen:

  • Es ist eine DLL, die den Clients in ihrer Anwendung zur Verfügung gestellt wird.
  • ein analoges Beispiel für die Verwendung wäre ChargeCreditCard(CreditCardInfo i) - offensichtlich, wenn die ChargeCreditCard () -Methode fehlschlägt, ist es eine große Sache; Ich bin mir nur nicht 100% ig sicher, ob ich die Druckmaschinen stoppen oder diese Verantwortung an den Kunden weitergeben sollte.

Bearbeiten Sie die zweite: Grundsätzlich bin ich nicht ganz davon überzeugt, welche dieser beiden Methoden zu verwenden:

%Vor%

oder

%Vor%

z.B. Wenn ein Benutzer versucht, eine Kreditkarte zu belasten, wird die Karte wirklich als außergewöhnlicher Umstand abgelehnt? Gehe ich zu weit in das Kaninchenloch, indem ich diese Frage stelle?

    
Whisker 14.11.2011, 17:36
quelle

3 Antworten

6

Hier ist eine kurze Liste von Dingen, die Sie beachten sollten. Obwohl nicht umfassend, glaube ich, dass diese Dinge Ihnen helfen können, besseren Code zu schreiben. Fazit: Behandeln Sie die Ausnahmebehandlung nicht unbedingt als böse. Stellen Sie sich beim Schreiben stattdessen die Frage: Wie gut kann ich das Problem, das ich löse, wirklich verstehen? In den meisten Fällen wird dies Ihnen helfen, ein besserer Entwickler zu werden.

  1. Können andere Entwickler das lesen? Kann es vom durchschnittlichen Entwickler vernünftigerweise verstanden werden ? Beispiel: ServiceConnectionException vs. eine verwirrende ServiceDisconnectedConnectionStatusException
  2. Im Falle des Auslösens einer Ausnahme, wie Ausnahme ist der Umstand? Was muss der Aufrufer tun, um die Methode zu implementieren?
  3. Ist diese Ausnahme fatal? Kann wirklich etwas mit dieser Ausnahme gemacht werden, wenn es gefangen wird? Threads abbrechen, nicht genügend Arbeitsspeicher .. Sie können nichts nützliches tun. Fange es nicht.
  4. Ist die Ausnahme verwirrend? Nehmen wir an, Sie haben eine Methode namens Car GetCarFromBigString(string desc) , die eine Zeichenfolge akzeptiert und ein Objekt Car zurückgibt. Wenn der Hauptnutzungsfall für diese Methode darin besteht, ein Car -Objekt von diesem string zu erzeugen, werfen Sie keine Ausnahme auf, wenn ein Car nicht aus string ermittelt werden konnte. Schreiben Sie stattdessen eine Methode wie bool TryGetCarFromBigString(string desc, out Car) .
  5. Kann dies leicht verhindert werden? Kann ich etwas überprüfen, zum Beispiel die Größe eines Arrays oder einer Variablen, die null ist?

Aus Gründen der Lesbarkeit von Code können wir uns Ihren Kontext ansehen.

%Vor%

Sie können oben sehen, dass das Abfangen von CouldNotConnectToSomeServiceException in Beispiel 3 nicht notwendigerweise zu einer besseren Lesbarkeit führt, wenn der Kontext einfach ein Binär-Test ist. Beide arbeiten jedoch. Aber ist es wirklich notwendig? Ist dein Programm abgespritzt, wenn du keine Verbindung herstellen kannst? Wie kritisch ist es wirklich? Dies sind alles Faktoren, die Sie berücksichtigen müssen. Es ist schwer zu sagen, da wir nicht auf Ihren gesamten Code zugreifen können.

Sehen wir uns einige andere Optionen an, die wahrscheinlich zu Problemen führen.

%Vor%

und

%Vor%     
Bryan Crosby 14.11.2011, 18:28
quelle
3

Ich denke, Sie müssen einige Dinge in Ihrem Design berücksichtigen:

1) Wie wird auf die API zugegriffen? Wenn Sie es über Web-Services verfügbar machen, ist das Auslösen von Ausnahmen wahrscheinlich keine gute Idee. Wenn sich die API in einer DLL befindet, die Sie Benutzern in ihren Anwendungen zur Verfügung stellen, sind Ausnahmen möglicherweise in Ordnung.

2) Wie viel zusätzliche Daten müssen mit dem Rückgabewert transportiert werden, damit die Fehlerreaktion für den API-Verbraucher nützlich ist? Wenn Sie brauchbare Informationen in Ihrer Fehlernachricht (dh Benutzer-ID und Login) im Gegensatz zu einer Zeichenfolge mit eingebetteten Informationen bereitstellen müssen, können Sie entweder benutzerdefinierte Ausnahmen oder eine "ErrorEncountered" -Klasse verwenden, die den Fehlercode und andere verwendbare Informationen enthält . Wenn Sie nur einen Code zurückgeben müssen, kann ein ENum-Wert, der entweder Erfolg (0) oder Fehler (beliebiger Wert ungleich Null) angibt, angemessen sein.

3) Dies in der ursprünglichen Antwort vergessen: Ausnahmen sind im .NET-Framework teuer. Wenn Ihre API einmal von Zeit zu Zeit aufgerufen wird, muss dies nicht berücksichtigt werden. Wenn die API jedoch für jede Webseite aufgerufen wird, die beispielsweise auf einer Website mit hoher Zugriffsrate geschaltet wird, möchten Sie dies auf keinen Fall sein Ausnahmen werden ausgelöst, um auf einen Fehler bei der Anforderung hinzuweisen.

Die kurze Antwort ist also, dass es wirklich auf die genauen Umstände ankommt.

    
competent_tech 14.11.2011 17:50
quelle
2

Ich mag die Idee "Exceptions auslösen, um außergewöhnliche Bedingungen anzuzeigen". Sie müssen diesen Namen aus einem bestimmten Grund haben.

In einer regulären Anwendung würden Sie File.Exists() vor einem File.Open() verwenden, um zu verhindern, dass eine Ausnahme ausgelöst wird. Erwartete Fehler als Ausnahmen sind schwer zu handhaben.

In einer Client-Server-Umgebung möchten Sie möglicherweise verhindern, dass Sie zwei Anforderungen senden müssen, und eine FileOpenResponse -Klasse erstellen, um sowohl Status als auch Daten zu senden (wie in diesem Fall ein Dateihandle).

    
C.Evenhuis 14.11.2011 18:00
quelle

Tags und Links