ProgramlamaKıdemli Go Geliştirici

Go, recover ve panic fonksiyonlarını nasıl uygular? Güvenli bir şekilde goroutine içinde geri dönüş sağlamak için doğru kullanım sırası nedir?

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

Cevap

Go'da panic ('panic'), programda kritik bir hata sinyali vermek için kullanılır. Panic çağrıldıktan sonra, yürütme, yığın açılmaya başlar ve tüm deferred fonksiyonları çağrılır. Eğer yığında recover() ile bir fonksiyon varsa, bu fonksiyon paniği yakalayabilir ve işleyebilir — ancak recover yalnızca kendi goroutine'i içinde çalışır ve yalnızca defer'dan çağrıldığında geçerlidir.

Güvenli geri dönüş için önerilen desen:

func safe(fn func()) { defer func() { if r := recover(); r != nil { fmt.Println("Panic'tan kurtarıldı:", r) } }() fn() } go safe(func() { panic("başarısız!") // programın durmasına neden olmaz })

Unutulmaması gerekenler:

  • panic, mevcut goroutine'in yürütmesini ilk recover'a kadar sonlandırır
  • Recover, yalnızca kendi goroutine'i içinde defer'dan çağrıldığında çalışır
  • Eğer recover kullanılmazsa, panic tüm programın sonlanmasına neden olur

Kandırmaca Soru

Recover, başka bir goroutine'de meydana gelen paniği yakalayabilir mi?

Cevap: Hayır, recover yalnızca panic'in meydana geldiği goroutine içinde çalışır ve yalnızca defer fonksiyonundan çağrıldığında geçerlidir. Eğer bir goroutine içinde panic oluşmuşsa ve recover başka bir goroutine içinde çağrılıyorsa — yakalama gerçekleşmez, program acil olarak sonlanır.

Örnek:

func main() { go func() { panic("goroutine içinde") }() time.Sleep(time.Second) recover() // Çalışmayacak! Panic programı sonlandıracak }

Gerçek Hatalar Örnekleri


Hikaye

Geliştirici, hata işleme için yalnızca ana fonksiyonda defer recover() deseni uyguladı. Bir işçi içinde bir goroutine'de panic meydana geldiğinde, tüm program acil olarak sonlandı - hata global recover tarafından yakalanmadı.


Hikaye

Projede, web sunucusunun düzgün kapatılması için defer/recover kullanıldı, bunun yeterli olduğunu düşündüler. Görüldü ki, bir goroutine'deki panic tüm süreci sonlandırıyordu çünkü recover'in işlenmesi gerektiği yerde değildi - tüm işçi havuzunu yeniden yapılandırmak zorunda kaldılar.


Hikaye

Mesaj işleme akışında, kullanıcı fonksiyonunun yanlış çalışmasından dolayı bir panic oluştu. Geliştirici, bunun üst düzeydeki recover tarafından "yakalanacağını" umuyordu, ancak recover'in yalnızca defer'dan çalıştığını fark etmedi. Sonuç olarak, hizmet, kuyrukta hatalı bir mesaj oluşunca düzensiz olarak çöküyordu.