Pembungkusan Error (fmt.Errorf)
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 54 dari 107.
Ketika error melewati beberapa lapisan aplikasimu, mengetahui dari mana error berasal menjadi sangat penting. Fungsi fmt.Errorf di Go dengan kata kerja %w memungkinkanmu membungkus error, mempertahankan error asli sambil menambahkan konteks.
Pembungkusan error membuat rantai error. Setiap lapisan dapat menambahkan informasi tentang hal yang sedang dicoba saat error terjadi:
func ReadConfig(filename string) error {
data, err := os.ReadFile(filename)
if err != nil {
return fmt.Errorf("reading config file: %w", err)
}
// proses data...
return nil
}Verb %w bersifat khusus. Verb ini membungkus error asli di dalam error baru. Ini berbeda dari %v, yang hanya mengubah error menjadi string dan menghilangkan identitas error aslinya.
func LoadSettings() error {
err := ReadConfig("settings.json")
if err != nil {
return fmt.Errorf("loading settings: %w", err)
}
return nil
}Saat LoadSettings gagal, pesan error menampilkan seluruh rantai: "loading settings: reading config file: open settings.json: no such file or directory". Setiap lapisan menambahkan konteks, sehingga debug menjadi jauh lebih mudah.
error yang dibungkus tetap berisi error asli di dalamnya. Di pelajaran berikutnya, kamu akan belajar cara membuka bungkus error ini dan memeriksa isinya menggunakan errors.Is() dan errors.As().
Tantangan
MudahMari buat sistem pemrosesan pesanan yang menunjukkan pembungkusan error di beberapa lapisan. Kamu akan membuat rangkaian fungsi, setiap lapisan menambahkan konteks ke error sehingga kamu dapat melacak dengan mudah di mana masalah terjadi.
Kamu akan mengatur kodemu dalam dua file:
orders.go: Buat logika pemrosesan pesanan dengan beberapa lapisan yang membungkus error saat error diteruskan ke lapisan atas.Buat tiga fungsi yang membentuk rangkaian pemrosesan:
ValidateItem(itemID string) error- Mengembalikan error dengan pesan"item not found"jika itemID adalah"INVALID", jika tidak, mengembalikannilProcessOrder(orderID, itemID string) error- MemanggilValidateItem. Jika fungsi tersebut mengembalikan error, bungkus error dengan konteks:"processing order [orderID]: %w". Jika tidak, kembalikannilSubmitOrder(customerName, orderID, itemID string) error- MemanggilProcessOrder. Jika fungsi tersebut mengembalikan error, bungkus error dengan konteks:"submitting order for [customerName]: %w". Jika tidak, kembalikannil
Setiap lapisan harus menggunakan
fmt.Errorfdengan kata kerja%wuntuk membungkus error dari lapisan di bawahnya, sehingga membentuk rangkaian konteks.main.go: Baca detail pesanan dari input, panggilSubmitOrder, lalu tampilkan hasilnya. Jika terjadi error, cetak seluruh rangkaian error. Jika berhasil, cetak pesan konfirmasi.
Input berikut akan diberikan:
- Baris 1: Nama pelanggan
- Baris 2: ID pesanan
- Baris 3: ID item
Cetak hasilnya:
- Jika terjadi error:
Error: [full error chain] - Jika berhasil:
Order [orderID] submitted successfully for [customerName]
Misalnya, jika diberikan Alice, ORD-123, dan INVALID, outputmu seharusnya:
Error: submitting order for Alice: processing order ORD-123: item not foundPerhatikan bagaimana pesan error menampilkan seluruh rangkaiannya. Kamu dapat melacak masalah dari upaya pengiriman pesanan tingkat atas, melalui pemrosesan pesanan, hingga kegagalan validasi yang sebenarnya. Setiap lapisan menambahkan konteksnya sendiri menggunakan %w.
Jika diberikan Bob, ORD-456, dan ITEM-001, outputmu seharusnya:
Order ORD-456 submitted successfully for BobCoba sendiri
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Baca nama pelanggan
scanner.Scan()
customerName := scanner.Text()
// Baca ID pesanan
scanner.Scan()
orderID := scanner.Text()
// Baca ID barang
scanner.Scan()
itemID := scanner.Text()
// TODO: Panggil SubmitOrder dengan nilai input
// TODO: Jika terjadi error, cetak: Error: [rantai error lengkap]
// TODO: Jika berhasil, cetak: Order [orderID] submitted successfully for [customerName]
_ = customerName
_ = orderID
_ = itemID
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP di Go
File EksternalWorkspace Go dan modulePaket dan ImporNama yang Diekspor dan Tidak DieksporPengantar OOP di Gostruct sebagai classMendefinisikan method pada structPointer receiver vs value receiverInisialisasi structFungsi KonstruktorUlasan: Kalkulator Sederhana4Interface
Pengenalan InterfaceImplementasi ImplisitInterface sebagai KontrakInterface Kosong (any)Type AssertionType SwitchKomposisi InterfaceInterface Stringer & ErrorUlasan: Kalkulator Bentuk7Enkapsulasi
Field yang Diekspor vs Tidak DieksporEnkapsulasi Tingkat PackageMethod Getter dan SetterPenyembunyian Informasi di GoRingkasan: Data Siswa10Generics (Go 1.18+)
Pengantar GenericsParameter TipeBatasan TipeStruct GenerikCara Alternatif untuk Method GenerikRingkasan Koleksi Generik2Mendalami Tipe dan Struct
Tipe Dasar dan KompositDefinisi Tipe KustomTag StructStruct AnonimStruct BersarangNilai Nol dan Nilai BawaanRangkuman: Buku Kontak5Komposisi daripada Pewarisan
Mengapa Go Tidak Memiliki PewarisanDasar Penyematan StructPromosi methodMenyematkan Beberapa StructPenyematan vs AgregasiMembayangi method yang DisematkanRangkuman: Hierarki Karyawan8Penanganan Error & OOP
Interface errorTipe Error KustomPembungkusan Error (fmt.Errorf)Error Sentinelerrors.Is() dan errors.As()Panic, Defer, dan RecoverRangkuman: Parser File3Pointer dan Memori
Dasar-Dasar Pointer di GoPointer ke StructPass by Value vs ReferenceFungsi new()Garbage Collection di GoRekap: Pembuat Linked List6Polimorfisme di Go
Polimorfisme melalui InterfaceDuck Typing di GoAturan Pemenuhan InterfaceKoleksi PolimorfikInjeksi DependensiRangkuman: Pemroses Pembayaran9Konkruensi & OOP
Dasar-dasar GoroutineChannel & KomunikasiChannel Ber-buffer vs Tanpa BufferPernyataan selectsync.Mutex & sync.RWMutexsync.WaitGroupDesain Struct yang Aman untuk ThreadRingkasan: Worker PoolLatihan sendiri: Compiler Go online