Direct naar de hoofdinhoud
Module 6 · Les 5 van 530/50 in de cursus~14 min
Modulelessen (5/5)

De foutinterface

error in Go is geen trefwoord: het is een ingebouwde interface met een enkele methode.

Go
type error interface {
    Error() string
}

Alles met Error() string is een error. Gecombineerd met de conventie voor het retourneren van (T, error) uit functies, het is de basis van foutafhandeling in Go.

Sentinel-fouten

Go
import "errors"

var ErrNotFound = errors.New("non trovato")

func find(key string) (string, error) {
    // ...
    return "", ErrNotFound
}

Een sentinel is een geëxporteerde error waarde die de beller kan vergelijken om een specifiek foutgeval te herkennen.

Aangepaste fouten (met gegevens)

Om context (bijvoorbeeld de ontbrekende sleutel) over te brengen, definieert u een type:

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}
}

fouten.Is en fouten.As (Go 1.13+)

Vergelijken met == werkt alleen voor "pure" schildwachten. Robuust zijn tegen ingepakte fouten gebruikt u het pakket errors:

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): waar als het doel zich ergens in de verpakkingsketen bevindt.
  • errors.As(err, &target): wijst toe dat de eerste fout in de keten van zijn type wordt aangepakt.

Wikkelen met %w

Go
if err := find("k"); err != nil {
    return fmt.Errorf("operazione X: %w", err)
}

%w (NIET %s of %v) creëert een nieuwe fout die de origineel, waardoor de keten navigeerbaar blijft via errors.Is/As.

Behandelingspatroon

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

Idioom:

  • Controleer err != nil onmiddellijk, geen "vroeg gelukkig pad".
  • Voeg context toe op elk niveau met fmt.Errorf("... : %w", err).
  • "Upstream" (dichtbij hoofd/handler), maak onderscheid met errors.Is/As.

Probeer het

Oefening#go.m6.l5.e1
Pogingen: 0Laden…

Implementeer de Error()-reeks op *ErrNotFound, zodat deze 'non trovato: <Key>' retourneert.

Editor laden…
Toon hint

`fmt.Println(err)` roept automatisch de Error() methode op uw struct aan.

Oplossing beschikbaar na 3 pogingen

Oefening#go.m6.l5.e2
Pogingen: 0Laden…

Gebruik fouten.Is om te controleren of err gelijk is aan de schildwacht ErrVuoto.

Editor laden…
Toon hint

`errors.Is(err, target)` is robuust, zelfs met wikkelkettingen.

Oplossing beschikbaar na 3 pogingen

Quiz#go.m6.l5.e3
Klaar

Wat is de exacte handtekening van de methode om fouten te implementeren?

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

Samenvatten

  • error = interface { Error() string }, ingebouwd.
  • Sentinels met errors.New("...") voor bekende gevallen zonder context.
  • Aangepaste fouttypen met velden om context te bevatten.
  • errors.Is(err, target): vergelijking robuust met inpakken.
  • errors.As(err, &target): extractie van de betonsoort.
  • fmt.Errorf("...: %w", err): verpakking die de ketting beschermt.
  • Nooit %v / %s inpakken: gebruik ALTIJD %w.