ProgramlamaGo Geliştirici

Go'da hata (errors) işlemleri nasıl çalışır: işleme yaklaşımları nelerdir, hataların fırlatılmak yerine geri dönmesi neden tercih edilir ve nasıl kendi hata türlerini oluşturabiliriz?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

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 }

Aldatıcı soru.

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.

Konuyla ilgili bilgi eksikliği nedeniyle yaşanan gerçek hata örnekleri.


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ı.