Hataları Sarma ve Açma
%w, errors.Is ve errors.As kullanma
Hataları Sarma ve Açma, CoddyKit'te ücretsiz bir Go Academy dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Go Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Go Academy kursu toplamda 4 dersten oluşur.
Hata Sarmalama Nedir?
Hata sarmalama, özgün hatayı yeni bir hatanın içine yerleştirir. Böylece bağlam eklenirken özgün hata program tarafından incelenebilir durumda korunur. Bu özellik Go 1.13'te düzgün biçimde kullanıma sunulmuştur:
package main
import ("fmt"; "errors")
var ErrDB = errors.New("database unreachable")
func queryUsers() error {
return fmt.Errorf("queryUsers: %w", ErrDB)
}
func loadProfile(id int) error {
return fmt.Errorf("loadProfile(%d): %w", id, queryUsers())
}
func main() {
err := loadProfile(42)
fmt.Println(err) // loadProfile(42): queryUsers: database unreachable
}%w Biçim Belirteci
Bir hatayı sarmalamak için fmt.Errorf içinde %v yerine %w kullanın. Sarmalanan hataya errors.Unwrap aracılığıyla erişilebilir:
package main
import ("fmt"; "errors")
func main() {
inner := errors.New("inner error")
outer := fmt.Errorf("outer: %w", inner)
fmt.Println(outer) // outer: inner error
fmt.Println(errors.Unwrap(outer)) // inner error
fmt.Println(errors.Is(outer, inner)) // true
}errors.Unwrap
errors.Unwrap, zincirdeki bir sonraki hatayı (sarmalanan hatayı) döndürür; zincirin sonuna ulaşıldıysa nil döndürür:
package main
import ("fmt"; "errors")
type Layer struct{ msg string; err error }
func (l *Layer) Error() string { return l.msg }
func (l *Layer) Unwrap() error { return l.err }
func main() {
root := errors.New("root")
mid := &Layer{"mid", root}
top := &Layer{"top", mid}
fmt.Println(errors.Unwrap(top)) // mid
fmt.Println(errors.Unwrap(mid)) // root
fmt.Println(errors.Unwrap(root)) // <nil>
}errors.Is — Zincirde Gezinme
errors.Is(err, target), bir eşleşme bulana veya nil değerine ulaşana kadar hata zincirini yinelemeli olarak açar:
package main
import ("fmt"; "errors")
var ErrNotFound = errors.New("not found")
func findItem(id int) error {
return fmt.Errorf("findItem(%d): %w",
id, fmt.Errorf("repo: %w", ErrNotFound))
}
func main() {
err := findItem(7)
fmt.Println(errors.Is(err, ErrNotFound)) // true — deep in chain
fmt.Println(err) // full message chain
}errors.As — Türler İçin Zincirde Gezinme
errors.As(err, &target), hedefin türüne atanabilen bir hata arayarak zincirde ilerler:
package main
import ("fmt"; "errors")
type StatusError struct{ Code int }
func (e *StatusError) Error() string { return fmt.Sprintf("status %d", e.Code) }
func doRequest() error {
return fmt.Errorf("request: %w", &StatusError{503})
}
func main() {
err := doRequest()
var se *StatusError
if errors.As(err, &se) {
fmt.Println("status code:", se.Code) // 503
}
}Zincirler İçin Özel Unwrap
errors.Is ve errors.As desteği sağlamak için özel hata türünüzde Unwrap() error uygulayın:
package main
import ("fmt"; "errors")
type AppError struct {
Op string
Err error
}
func (e *AppError) Error() string { return fmt.Sprintf("%s: %v", e.Op, e.Err) }
func (e *AppError) Unwrap() error { return e.Err }
var ErrAuth = errors.New("unauthorized")
func main() {
err := &AppError{"login", ErrAuth}
fmt.Println(errors.Is(err, ErrAuth)) // true
}fmt.Errorf İçinde %v ve %w Karşılaştırması
%v ile %w arasındaki fark:
package main
import ("fmt"; "errors")
func main() {
inner := errors.New("inner")
withV := fmt.Errorf("outer: %v", inner) // string only, no wrap
withW := fmt.Errorf("outer: %w", inner) // wraps inner
fmt.Println(errors.Is(withV, inner)) // false — not wrapped
fmt.Println(errors.Is(withW, inner)) // true — wrapped
}Uygulamada Sarmalama: HTTP İşleyicisi
Tutarlı hata sarmalama, üretim sistemlerinde hata ayıklamayı kolaylaştırır:
package main
import "fmt"
func dbQuery(sql string) error {
return fmt.Errorf("db.Query(%q): connection refused", sql)
}
func getUserByID(id int) (string, error) {
if err := dbQuery("SELECT * FROM users WHERE id=?"); err != nil {
return "", fmt.Errorf("getUserByID(%d): %w", id, err)
}
return "Alice", nil
}
func handler() error {
_, err := getUserByID(1)
if err != nil {
return fmt.Errorf("handler: %w", err)
}
return nil
}
func main() { fmt.Println(handler()) }errors.Join — Birden Çok Sarmalama (Go 1.20+)
errors.Join, birden çok hatayı saran bir hata oluşturur. errors.Is bunların tümünü denetler:
package main
import ("fmt"; "errors")
var ErrA = errors.New("err A")
var ErrB = errors.New("err B")
func main() {
joined := errors.Join(ErrA, ErrB)
fmt.Println(joined)
fmt.Println(errors.Is(joined, ErrA)) // true
fmt.Println(errors.Is(joined, ErrB)) // true
}Sarmalamayı Geri Açma İçin En İyi Uygulamalar
Hata sarmalama yönergeleri:
- Program tarafından incelenebilmesi için hatayı korumak üzere
%wile sarın - Bağlam için işlem adını ekleyin:
fmt.Errorf("funcName: %w", err) - Çağıranlar
errors.Iskullanmayacaksa önceden tanımlı hataları sarmalamayın - Aynı bağlamı her düzeyde iki kez sarmalamaktan kaçının
- Zincirlere katılmak için özel türlerde
Unwrap()uygulayın
Hızlı Kontrol
fmt.Errorf içinde %v ve %w kullanımı arasındaki fark nedir?
Özet: Hata Sarmalama ve Geri Açma
Özet:
fmt.Errorf("ctx: %w", err), bağlamla birlikte sararerrors.Unwrap, zincirdeki bir sonraki hatayı alırerrors.Is, özdeşlik eşleşmesi için zincirde ilerlererrors.As, tür eşleşmesi için zincirde ilerler- Özel türler
Unwrap() erroruygular errors.Join, birden çok hatayı sarar (Go 1.20+)
Sıkça Sorulan Sorular
“Hataları Sarma ve Açma” dersi ücretsiz mi?
Evet — “Hataları Sarma ve Açma” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Go Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Go Academy kursu toplamda 4 dersten oluşur.
“Hataları Sarma ve Açma” dersinde ne öğreneceğim?
%w, errors.Is ve errors.As kullanma Go Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
Go Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Go Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.
“Hataları Sarma ve Açma” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu Go Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Go Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- error Arayüzü
- Özel Hatalar Oluşturma
- Hataları Sarma ve Açma
- panic, recover ve defer