Lekcje modułu (5/5)
Interfejs error
error w Go nie jest słowem kluczowym: to wbudowany interfejs z plikiem
pojedyncza metoda.
type error interface {
Error() string
}Wszystko, co ma Error() string, jest error. W połączeniu z
konwencja zwracania (T, error) z funkcji, to jest
podstawy obsługi błędów w Go.
Błędy Sentinela
import "errors"
var ErrNotFound = errors.New("non trovato")
func find(key string) (string, error) {
// ...
return "", ErrNotFound
}wartownik to wyeksportowana wartość error, którą może wywołać osoba wywołująca
porównać z, aby rozpoznać konkretny przypadek błędu.
Błędy niestandardowe (z danymi)
Aby przenieść kontekst (np. brakujący klucz), definiujesz 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}
}błędy.Is i błędy.As (wersja 1.13+)
Porównanie z == działa tylko w przypadku „czystych” strażników. Być solidnym
przed opakowanymi błędami użyj pakietu 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): prawda, jeśli cel znajduje się gdzieś w łańcuchu zawijania.errors.As(err, &target): przypisuje cel do pierwszego błędu w łańcuchu tego typu.
Zawijanie za pomocą %w
if err := find("k"); err != nil {
return fmt.Errorf("operazione X: %w", err)
}%w (NIE %s lub %v) tworzy nowy błąd, który zawija
oryginał, utrzymując nawigację po łańcuchu za pomocą errors.Is/As.
Wzór obsługi
v, err := op()
if err != nil {
return fmt.Errorf("op fallita per %q: %w", id, err)
}Frazeologia:
- Sprawdź
err != nilnatychmiast, bez „wczesnej szczęśliwej ścieżki”. - Dodaj kontekst na każdym poziomie za pomocą
fmt.Errorf("... : %w", err). - „Upstream” (w pobliżu głównego / modułu obsługi), rozróżniaj za pomocą
errors.Is/As.
Spróbuj
Zaimplementuj ciąg Error() w *ErrNotFound, aby zwracał „non trovato: <Key>”.
Pokaż wskazówkę
`fmt.Println(err)` automatycznie wywołuje metodę Error() w Twojej strukturze.
Rozwiązanie dostępne po 3 próbach
Użyj błędów. Służy do sprawdzania, czy err jest równy wartownikowi ErrVuoto.
Pokaż wskazówkę
`errors.Is(err, target)` jest wytrzymały nawet w przypadku łańcuchów owijających.
Rozwiązanie dostępne po 3 próbach
Jaki jest dokładny podpis metody implementacji błędu?
func (e *MyErr) ??? {}Podsumowanie
error = interface { Error() string }, wbudowany.- Strażnicy z
errors.New("...")dla znanych przypadków bez kontekstu. - Niestandardowe typy błędów z polami do przenoszenia kontekstu.
errors.Is(err, target): porównanie odporne na pakowanie.errors.As(err, &target): ekstrakcja typu betonowego.fmt.Errorf("...: %w", err): opakowanie chroniące łańcuch.- Nigdy nie zawijaj
%v/%s: ZAWSZE używaj%w.