Go'da hataların işlenmesi için standart yöntem, fonksiyondan error tipinde bir değer döndürmektir. İstisnaların (exceptions) kullanıldığı dillerin aksine, Go'da istisnalar (panic, recover) yalnızca gerçekten olağanüstü durumlar için kullanılır; iş mantığı için normal hatalar kullanılmalıdır.
Klasik yöntem:
func doSomething() error { // ... return nil // veya errors.New("some error") } err := doSomething() if err != nil { // hata işlemesi }
Daha detaylı analiz için kendi hata türlerinizi oluşturabilirsiniz:
type MyError struct { Code int Message string } func (e *MyError) Error() string { return fmt.Sprintf("(%d) %s", e.Code, e.Message) } err := &MyError{404, "not found"}
Belirli bir hatayı kontrol etmenin tipik bir yolu:
if myErr, ok := err.(*MyError); ok && myErr.Code == 404 { // 404 hata işlemesi }
Go'da hata ile nil karşılaştırması
==ile yapılabilir mi?
Cevap: Evet, hata bulunmadığını kontrol etmek için yapılabilir ve yapılmalıdır. Ancak unutulmaması gereken önemli bir nokta: eğer hata sarıldıysa veya nil içeren yapılarla oluşturulduysa, karşılaştırma yanlış olabilir. Örneğin:
var err error = (*MyError)(nil) fmt.Println(err == nil) // false!
Hata, arayüz nil değilse, tipi nil değilse nil ile eşit değildir, içindeki değer nil olsa bile.
Hikaye
Mikroservis, hata kayıt işlemlerini nil ile karşılaştırarak yapıyordu. Geliştiricilerden biri, (*MyError)(nil) gibi tiplenmiş bir hata döndürüyordu ve bunun nil ile eşdeğer olmadığını fark etmiyordu (arayüz nil değil). Sonuç olarak, hata işlemesi çalışmayı durdurdu ve birçok yanlış uyarı metriklere düştü.
Hikaye
Projede hataları zincirleme ile iletmek yerine, tüm hatalar için panic kullanarak bunun "temiz" bir yol olduğunu düşündüler. Bu, kullanıcının geçersiz giriş yapması durumunda uygulamanın çökmesine neden oldu çünkü panic/recover akışa dayalı iş mantığı için tasarlanmamıştır.
Hikaye
Hata birkaç kez fmt.Errorf("some: %w", err) ile sarıldı ve belirli bir hata tipine kontrol yaparken sıradan bir karşılaştırma yapıldı, errors.Is ve errors.As kullanmak yerine. Bu, iş mantığının özel hata türlerine yanıt vermemesine neden oldu, oysa ki iç içe geçmiş hatada gerçekten vardı.