Menu
Coddy logo textTech

Hata Sarmalama (fmt.Errorf)

Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 54 / 107.

Hatalar uygulamanızın birden çok katmanından geçtiğinde, bir hatanın nerede kaynaklandığını bilmek kritik hâle gelir. Go'nun fmt.Errorf işlevi ve %w fiili, hataları sarmalamanıza, bağlam eklerken özgün hatayı korumanıza olanak tanır.

Hata sarmalama bir hata zinciri oluşturur. Her katman, hata oluştuğunda ne yapmaya çalıştığı hakkında bilgi ekleyebilir:

func ReadConfig(filename string) error {
    data, err := os.ReadFile(filename)
    if err != nil {
        return fmt.Errorf("reading config file: %w", err)
    }
    // veriyi işle...
    return nil
}

%w fiili özeldir. Özgün hatayı yeni hatanın içine sarar. Bu, hatayı yalnızca bir dizeye dönüştüren ve özgün hatanın kimliğini kaybeden %v'den farklıdır.

func LoadSettings() error {
    err := ReadConfig("settings.json")
    if err != nil {
        return fmt.Errorf("loading settings: %w", err)
    }
    return nil
}

LoadSettings başarısız olduğunda hata mesajı tam zinciri gösterir: "loading settings: reading config file: open settings.json: no such file or directory". Her katman bağlam ekleyerek hata ayıklamayı çok daha kolaylaştırır.

Sarmalanmış hata hâlâ kendi içinde özgün hatayı barındırır. Bir sonraki derste, bu hataları nasıl açacağınızı ve errors.Is() ile errors.As() kullanarak içlerinde ne olduğunu nasıl kontrol edeceğinizi öğreneceksiniz.

challenge icon

Görev

Kolay

Birden çok katmanda hata sarmalamayı gösteren bir sipariş işleme sistemi oluşturalım. Her katmanın hatalara bağlam eklediği bir işlev zinciri oluşturacak ve sorunların tam olarak nerede meydana geldiğini kolayca izleyeceksin.

Kodunu iki dosyaya ayıracaksın:

  • orders.go: Hatalar yukarı doğru yayılırken onları sarmalayan birden çok katmanla sipariş işleme mantığını oluştur.

    Bir işleme zinciri oluşturan üç işlev uygula:

    • ValidateItem(itemID string) error - itemID "item not found" ise "INVALID" mesajıyla bir hata döndürür, aksi durumda nil döndürür
    • ProcessOrder(orderID, itemID string) error - ValidateItem işlevini çağırır. Bir hata döndürürse hatayı şu bağlamla sarar: "processing order [orderID]: %w". Aksi durumda nil döndürür
    • SubmitOrder(customerName, orderID, itemID string) error - ProcessOrder işlevini çağırır. Bir hata döndürürse hatayı şu bağlamla sarar: "submitting order for [customerName]: %w". Aksi durumda nil döndürür

    Her katman, aşağıdaki katmandan gelen hatayı sarmalamak ve bir bağlam zinciri oluşturmak için fmt.Errorf fiiliyle birlikte %w kullanmalıdır.

  • main.go: Sipariş ayrıntılarını girdiden oku, SubmitOrder işlevini çağır ve sonucu görüntüle. Bir hata oluşursa hata zincirinin tamamını yazdır. Başarılı olursa bir onay mesajı yazdır.

Aşağıdaki girdiler sağlanacaktır:

  • 1. satır: Müşteri adı
  • 2. satır: Sipariş kimliği
  • 3. satır: Ürün kimliği

Sonucu yazdır:

  • Bir hata oluşursa: Error: [full error chain]
  • Başarılı olursa: Order [orderID] submitted successfully for [customerName]

Örneğin, Alice, ORD-123 ve INVALID verildiğinde çıktın şu şekilde olmalıdır:

Error: submitting order for Alice: processing order ORD-123: item not found

Hata mesajının zincirin tamamını nasıl gösterdiğine dikkat et. Sorunu üst düzey gönderim denemesinden sipariş işleme aşamasına ve oradan gerçek doğrulama hatasına kadar izleyebilirsin. Her katman, kendi bağlamını %w kullanarak ekledi.

Benzer şekilde, Bob, ORD-456 ve ITEM-001 verildiğinde çıktın şu şekilde olmalıdır:

Order ORD-456 submitted successfully for Bob

Kendin dene

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Müşteri adını oku
	scanner.Scan()
	customerName := scanner.Text()
	
	// Sipariş ID'sini oku
	scanner.Scan()
	orderID := scanner.Text()
	
	// Ürün ID'sini oku
	scanner.Scan()
	itemID := scanner.Text()
	
	// TODO: Giriş değerleriyle SubmitOrder'ı çağır
	// TODO: Bir hata oluşursa yazdır: Error: [full error chain]
	// TODO: If successful, print: Order [orderID] submitted successfully for [customerName]
	
	_ = customerName
	_ = orderID
	_ = itemID
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Go derleyicisi