Lektionen des Moduls (5/5)
Das error-Interface
error in Go ist kein Schlüsselwort: Es ist eine integrierte Schnittstelle mit a
Einzelmethode.
type error interface {
Error() string
}Alles, was Error() string hat, ist ein error. Kombiniert mit dem
Konvention, (T, error) von Funktionen zurückzugeben, ist es die
Grundlage der Fehlerbehandlung in Go.
Sentinel-Fehler
import "errors"
var ErrNotFound = errors.New("non trovato")
func find(key string) (string, error) {
// ...
return "", ErrNotFound
}Ein Sentinel ist ein exportierter error-Wert, den der Anrufer abrufen kann
vergleichen, um einen bestimmten Fehlerfall zu erkennen.
Benutzerdefinierte Fehler (mit Daten)
Um den Kontext (z. B. den fehlenden Schlüssel) zu übertragen, definieren Sie einen Typ:
type ErrNotFound struct {
Key string
}
func (e *ErrNotFound) Error() string {
return "non trovato: " + e.Key
}
func find(key string) (string, error) {
return "", &ErrNotFound{Key: key}
}##errors.Is underrors.As (Go 1.13+)
Der Vergleich mit == funktioniert nur für „reine“ Sentinels. Robust sein
Gegen verpackte Fehler verwenden Sie das errors-Paket:
import "errors"
if errors.Is(err, ErrNotFound) {
// err IS ErrNotFound (even if wrapped)
}
var nfe *ErrNotFound
if errors.As(err, &nfe) {
// err IS (or wraps) an *ErrNotFound; nfe points to the concrete value
fmt.Println("chiave mancante:", nfe.Key)
}– errors.Is(err, target): wahr, wenn sich das Ziel irgendwo in der Wrapping-Kette befindet.
errors.As(err, &target): weist dem Ziel den ersten Fehler in der Kette seines Typs zu.
Umbruch mit %w
if err := find("k"); err != nil {
return fmt.Errorf("operazione X: %w", err)
}%w (NICHT %s oder %v) erstellt einen neuen Fehler, der das umschließt
Original, sodass die Kette mit errors.Is/As navigierbar bleibt.
Handhabungsmuster
v, err := op()
if err != nil {
return fmt.Errorf("op fallita per %q: %w", id, err)
}Redewendungen:
- Überprüfen Sie
err != nilsofort, kein „early happy path“. - Fügen Sie mit
fmt.Errorf("... : %w", err)Kontext auf jeder Ebene hinzu. - „Upstream“ (in der Nähe von Haupt-/Handler), unterscheiden Sie mit
errors.Is/As.
Probieren Sie es aus
Implementieren Sie die Zeichenfolge Error() in *ErrNotFound, sodass „non trovato: <Key>“ zurückgegeben wird.
Hinweis anzeigen
`fmt.Println(err)` ruft automatisch die Error()-Methode Ihrer Struktur auf.
Lösung nach 3 Versuchen verfügbar
Verwenden Sie „errors.Is“, um zu prüfen, ob err dem Sentinel ErrVuoto entspricht.
Hinweis anzeigen
`errors.Is(err, target)` ist auch bei Wickelketten robust.
Lösung nach 3 Versuchen verfügbar
Wie lautet die genaue Signatur der Methode zur Fehlerimplementierung?
func (e *MyErr) ??? {}Zusammenfassung
error = interface { Error() string }, integriert.- Sentinels mit
errors.New("...")für bekannte Fälle ohne Kontext. - Benutzerdefinierte Fehlertypen mit Feldern zur Übertragung des Kontexts.
errors.Is(err, target): Vergleich robust gegenüber Wrapping.errors.As(err, &target): Extraktion des Betontyps.fmt.Errorf("...: %w", err): Umhüllung, die die Kette erhält.- Niemals
%v/%szum Umbrechen verwenden: Verwenden Sie IMMER%w.