Menu
CoddyTech

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().

challenge icon

Tantangan

Mudah

Mari 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, mengembalikan nil
    • ProcessOrder(orderID, itemID string) error - Memanggil ValidateItem. Jika fungsi tersebut mengembalikan error, bungkus error dengan konteks: "processing order [orderID]: %w". Jika tidak, kembalikan nil
    • SubmitOrder(customerName, orderID, itemID string) error - Memanggil ProcessOrder. Jika fungsi tersebut mengembalikan error, bungkus error dengan konteks: "submitting order for [customerName]: %w". Jika tidak, kembalikan nil

    Setiap lapisan harus menggunakan fmt.Errorf dengan kata kerja %w untuk membungkus error dari lapisan di bawahnya, sehingga membentuk rangkaian konteks.

  • main.go: Baca detail pesanan dari input, panggil SubmitOrder, 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 found

Perhatikan 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 Bob

Coba 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
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Go online