Sollte ein Go-Paket jemals log.Fatal verwenden und wann?

9

Ich habe bisher die Verwendung von log.Fatal vermieden, aber ich habe kürzlich zufällig diese Fragen entdeckt; Code-Coverage und tests-using-log-fatal .

Einer der Kommentare aus den 100 Code-Coverage-Fragen lautet:

  

... In den allermeisten Fällen sollte log.Fatal nur in main- oder init-Funktionen verwendet werden (oder möglicherweise in einigen Dingen, die nur direkt von ihnen aufgerufen werden sollen) "

Es geht mir nach, also begann ich mir den Standard-Bibliothekscode anzusehen, der mit Go geliefert wurde. Es gibt viele Beispiele, bei denen der Code test in der Bibliothek log.Fatal verwendet, was gut zu sein scheint. Es gibt einige Beispiele außerhalb des Testcodes, z. B. in net/http , unten gezeigt:

%Vor%

Wenn es die empfohlene Vorgehensweise ist, die Verwendung von log.Fatal zu vermeiden, warum wird sie überhaupt in den Standardbibliotheken verwendet, hätte ich nur einen Fehler zurückgegeben. Es scheint unfair für den Benutzer der Bibliothek zu sein, dass os.Exit aufgerufen wird und keine Möglichkeit für die Anwendung besteht, eine Bereinigung durchzuführen.

Ich bin vielleicht naiv, daher scheint meine Frage eine bessere Praxis zu sein, log.Panic zu nennen, die wiederhergestellt werden kann, und meine theoretisch lang laufende stabile Anwendung könnte eine Chance haben, aus der Asche aufzusteigen.

Was würde also Best-Practice sagen für wann sollte log.Fatal verwendet werden?

    
miltonb 24.11.2015, 04:02
quelle

1 Antwort

8

Es könnte nur ich sein, aber hier verwende ich log.Fatal . Gemäß den UNIX-Konventionen sollte ein Prozess, bei dem ein Fehler auftritt, so früh wie möglich mit einem Nicht-Null-Beendigungscode fehlschlagen. Dies führte mich zu den folgenden Richtlinien, um log.Fatal zu verwenden, wenn ...

  1. ... in meinem func init() ist ein Fehler aufgetreten, da dies bei der Verarbeitung der Importe oder vor dem Aufruf der Hauptfunktion der Fall ist. Umgekehrt mache ich nur Sachen, die nicht direkt die Arbeitseinheit beeinflussen, die die Bibliothek oder cmd ausführen soll. Zum Beispiel konfiguriere ich die Protokollierung und überprüfe, ob wir eine vernünftige Umgebung und Parameter haben. Keine Notwendigkeit, Main zu laufen, wenn wir ungültige Flaggen haben, richtig? Und wenn wir kein richtiges Feedback geben können, sollten wir dies früh sagen.
  2. ... ein Fehler passiert, von dem ich weiß, dass er unwiederbringlich ist. Nehmen wir an, wir haben ein Programm, das eine Miniaturansicht einer Bilddatei erstellt, die in der Befehlszeile angegeben wird. Wenn diese Datei nicht existiert oder aufgrund unzureichender Berechtigungen nicht lesbar ist, gibt es keinen Grund, fortzufahren, und dieser Fehler kann nicht wiederhergestellt werden. Also halten wir uns an die Konventionen und scheitern.
  3. ... während eines Prozesses, der möglicherweise nicht reversibel ist, tritt ein Fehler auf. Das ist eine Art weiche Definition, ich weiß. Lassen Sie mich das illustrieren. Nehmen wir an, wir haben eine Implementierung von cp , und es wurde begonnen, nicht interaktiv zu sein und ein Verzeichnis rekursiv zu kopieren. Nehmen wir nun an, dass wir im Zielverzeichnis eine Datei finden, die denselben Namen (aber unterschiedlichen Inhalt) hat wie eine Datei, die dort kopiert werden soll. Da wir den Benutzer nicht bitten können, zu entscheiden, was zu tun ist und wir diese Datei nicht kopieren können, haben wir ein Problem. Da der Benutzer davon ausgeht, dass die Quellen- und Zielverzeichnisse exakte Kopien sind, wenn wir mit dem Exit-Code Null fertig sind, können wir die betreffende Datei nicht einfach überspringen. Wir können es jedoch nicht einfach überschreiben, da dies möglicherweise Informationen zerstören könnte. Dies ist eine Situation, die wir nicht durch eine explizite Anfrage des Benutzers wiederherstellen können, und daher würde ich log.Fatal verwenden, um die Situation zu erklären und hiermit dem Prinzip zu folgen, so früh wie möglich zu versagen.
Markus W Mahlberg 24.11.2015, 09:40
quelle

Tags und Links