Lompati ke konten utama
Modul 6 · Pelajaran 5 dari 530/50 dalam kursus~14 min
Pelajaran modul (5/5)

Antarmuka kesalahan

error di Go bukanlah kata kunci: ini adalah antarmuka bawaan dengan metode tunggal.

Go
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

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

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

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:

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

Go
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

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

Idiom:

  • Periksa err != nil segera, 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

Latihan#go.m6.l5.e1
Upaya: 0Memuat…

Implementasikan string Error() pada *ErrNotFound sehingga mengembalikan 'non trovato: <Key>'.

Memuat editor…
Tunjukkan petunjuk

`fmt.Println(err)` secara otomatis memanggil metode Error() pada struct Anda.

Solusi tersedia setelah 3 upaya

Latihan#go.m6.l5.e2
Upaya: 0Memuat…

Gunakan error.Is untuk memeriksa apakah err sama dengan penjaga ErrVuoto.

Memuat editor…
Tunjukkan petunjuk

`errors.Is(err, target)` kuat bahkan dengan rantai pembungkus.

Solusi tersedia setelah 3 upaya

Quiz#go.m6.l5.e3
Siap

Apa tanda pasti dari metode untuk mengimplementasikan kesalahan?

Go
func (e *MyErr) ??? {}
Pilihan jawaban

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 / %s untuk membungkus: SELALU gunakan %w.