ProgrammierungGo-Entwickler

Wie funktioniert die Fehlerbehandlung (errors) in Go: welche Ansätze zur Verarbeitung gibt es, warum werden Fehler normalerweise zurückgegeben und nicht geworfen, und wie kann man eigene Fehlertypen implementieren?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

In Go gibt es einen standardmäßigen Ansatz zur Fehlerbehandlung, indem der Rückgabetyp error aus einer Funktion zurückgegeben wird. Im Gegensatz zu Sprachen mit Ausnahmen werden in Go Ausnahmen (panic, recover) nur für wirklich außergewöhnliche Situationen verwendet; für Geschäftslogik sollte ein gewöhnlicher Fehler verwendet werden.

Der klassische Weg:

func doSomething() error { // ... return nil // oder errors.New("ein Fehler") } err := doSomething() if err != nil { // Fehlerbehandlung }

Sie können eigene Fehlertypen erstellen, um eine detailliertere Analyse durchzuführen:

type MyError struct { Code int Message string } func (e *MyError) Error() string { return fmt.Sprintf("(%d) %s", e.Code, e.Message) } err := &MyError{404, "nicht gefunden"}

Typische Überprüfung eines spezifischen Fehlertyps:

if myErr, ok := err.(*MyError); ok && myErr.Code == 404 { // Verarbeitung des Fehlers 404 }

Fangfrage.

Kann man error in Go mit nil mittels == vergleichen?

Antwort: Ja, man kann und sollte, um das Fehlen eines Fehlers zu überprüfen. Aber es ist wichtig zu beachten: Wenn der Fehler eingekapselt oder mit Fehlern erstellt wird, die nil innerhalb von Strukturen enthalten, kann der Vergleich falsch sein. Zum Beispiel:

var err error = (*MyError)(nil) fmt.Println(err == nil) // false!

Ein Fehler tritt auf, weil das Interface nicht nil ist, wenn sein Typ nicht nil ist, auch wenn der Wert innen nil ist.

Beispiele für reale Fehler aufgrund von Unkenntnis der Feinheiten des Themas.


Geschichte

Ein Mikroservice loggte Fehler durch Vergleich auf nil. Einer der Entwickler gab einen typisierten Fehler wie (*MyError)(nil) zurück, ohne zu bemerken, dass dies nicht gleich nil ist (das Interface ist nicht nil). Infolgedessen hörte die Fehlerbehandlung auf zu funktionieren und viele falsche Alarme gelangen in die Metriken.


Geschichte

Im Projekt wurde anstelle der Weitergabe von Fehlern in der Kette panic für alle Fehler verwendet, da dies als „saubere“ Methode angesehen wurde. Dies führte dazu, dass die Anwendung bei jeder ungültigen Benutzereingabe abstürzte, da panic/recover nicht für die streambasierte Geschäftslogik gedacht sind.


Geschichte

Der Fehler wurde mehrmals mit fmt.Errorf("some: %w", err) eingekapselt, und bei der Überprüfung auf einen bestimmten Fehlertyp wurde ein einfacher Vergleich anstelle der Verwendung von errors.Is und errors.As durchgeführt. Dies führte dazu, dass die Geschäftslogik nicht auf die benutzerdefinierten Fehlertypen reagierte, obwohl diese tatsächlich innerhalb des eingekapselten Fehlers vorhanden waren.