Direkt zum Hauptinhalt springen
eLearner.app
Modul 6 · Lektion 5 von 530/50 im Kurs~14 min
Lektionen des Moduls (5/5)

Das error-Interface

error in Go ist kein Schlüsselwort: Es ist eine integrierte Schnittstelle mit a Einzelmethode.

Go
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

Go
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:

Go
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:

Go
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

Go
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

Go
v, err := op()
if err != nil {
    return fmt.Errorf("op fallita per %q: %w", id, err)
}

Redewendungen:

  • Überprüfen Sie err != nil sofort, 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

Übung#go.m6.l5.e1
Versuche: 0Wird geladen…

Implementieren Sie die Zeichenfolge Error() in *ErrNotFound, sodass „non trovato: <Key>“ zurückgegeben wird.

Editor wird geladen…
Hinweis anzeigen

`fmt.Println(err)` ruft automatisch die Error()-Methode Ihrer Struktur auf.

Lösung nach 3 Versuchen verfügbar

Übung#go.m6.l5.e2
Versuche: 0Wird geladen…

Verwenden Sie „errors.Is“, um zu prüfen, ob err dem Sentinel ErrVuoto entspricht.

Editor wird geladen…
Hinweis anzeigen

`errors.Is(err, target)` ist auch bei Wickelketten robust.

Lösung nach 3 Versuchen verfügbar

Quiz#go.m6.l5.e3
Bereit

Wie lautet die genaue Signatur der Methode zur Fehlerimplementierung?

Go
func (e *MyErr) ??? {}
Antwortoptionen

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/%s zum Umbrechen verwenden: Verwenden Sie IMMER %w.