Modulelessen (5/5)
De foutinterface
error in Go is geen trefwoord: het is een ingebouwde interface met een
enkele methode.
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
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:
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:
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
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
v, err := op()
if err != nil {
return fmt.Errorf("op fallita per %q: %w", id, err)
}Idioom:
- Controleer
err != nilonmiddellijk, 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
Implementeer de Error()-reeks op *ErrNotFound, zodat deze 'non trovato: <Key>' retourneert.
Toon hint
`fmt.Println(err)` roept automatisch de Error() methode op uw struct aan.
Oplossing beschikbaar na 3 pogingen
Gebruik fouten.Is om te controleren of err gelijk is aan de schildwacht ErrVuoto.
Toon hint
`errors.Is(err, target)` is robuust, zelfs met wikkelkettingen.
Oplossing beschikbaar na 3 pogingen
Wat is de exacte handtekening van de methode om fouten te implementeren?
func (e *MyErr) ??? {}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/%sinpakken: gebruik ALTIJD%w.