Pelajaran modul (5/5)
Antarmuka kesalahan
error di Go bukanlah kata kunci: ini adalah antarmuka bawaan dengan
metode tunggal.
type error interface {
Error() string
}Apa pun yang memiliki Error() string adalah error. Dikombinasikan dengan
konvensi mengembalikan (T, error) dari fungsi, itulah
dasar penanganan kesalahan di Go.
Kesalahan penjaga
import "errors"
var ErrNotFound = errors.New("non trovato")
func find(key string) (string, error) {
// ...
return "", ErrNotFound
}sentinel adalah nilai error yang diekspor yang dapat digunakan oleh penelepon
bandingkan untuk mengenali kasus kesalahan tertentu.
Kesalahan khusus (dengan data)
Untuk membawa konteks (misalnya kunci yang hilang), Anda menentukan tipe:
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}
}error.Is dan error.As (Go 1.13+)
Membandingkan dengan == hanya berfungsi untuk penjaga "murni". Untuk menjadi kuat
terhadap kesalahan yang dibungkus, gunakan paket 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): benar jika target berada di suatu tempat dalam rantai pembungkus.errors.As(err, &target): menetapkan untuk menargetkan kesalahan pertama dalam rantai jenisnya.
Membungkus dengan %w
if err := find("k"); err != nil {
return fmt.Errorf("operazione X: %w", err)
}%w (BUKAN %s atau %v) membuat kesalahan baru yang membungkus
asli, menjaga rantai tetap dapat dinavigasi pada errors.Is/As.
Pola penanganan
v, err := op()
if err != nil {
return fmt.Errorf("op fallita per %q: %w", id, err)
}Idiom:
- Periksa
err != nilsegera, tidak ada "jalur bahagia awal". - Tambahkan konteks di setiap level dengan
fmt.Errorf("... : %w", err). - "Hulu" (dekat main/handler), bedakan dengan
errors.Is/As.
Cobalah
Implementasikan string Error() pada *ErrNotFound sehingga mengembalikan 'non trovato: <Key>'.
Tunjukkan petunjuk
`fmt.Println(err)` secara otomatis memanggil metode Error() pada struct Anda.
Solusi tersedia setelah 3 upaya
Gunakan error.Is untuk memeriksa apakah err sama dengan penjaga ErrVuoto.
Tunjukkan petunjuk
`errors.Is(err, target)` kuat bahkan dengan rantai pembungkus.
Solusi tersedia setelah 3 upaya
Apa tanda pasti dari metode untuk mengimplementasikan kesalahan?
func (e *MyErr) ??? {}Rekap
error = interface { Error() string }, bawaan.- Penjaga dengan
errors.New("...")untuk kasus yang diketahui tanpa konteks. - Jenis kesalahan khusus dengan bidang untuk membawa konteks.
errors.Is(err, target): perbandingan kuat untuk membungkus.errors.As(err, &target): ekstraksi jenis beton.fmt.Errorf("...: %w", err): pembungkus yang mengawetkan rantai.- Jangan pernah
%v/%suntuk membungkus: SELALU gunakan%w.