Goroutine'lerde Panic'i Yakalamak: Graceful Error Handling

Go'da goroutine'ler eşzamanlı işleri yönetmenin temel yolu olsa da, içinde panic oluşursa tüm program çöker. Ana goroutine'de recover yapsan bile, arkaplanda çalışan diğer goroutine'lerdeki panic'i yakalayamazsın.

Sorun şu: bir goroutine'de panic olursa, o goroutine'yi başlatan kod bunu bilmez ve program beklenmedik şekilde kapanır. Bunu önlemek için her goroutine'nin içinde defer ve recover kullanman gerekir.

Asıl çözüm, goroutine başlatmadan önce panic'i yakalayacak bir wrapper fonksiyon yazmanıdır.

1package main
2
3import (
4"fmt"
5"sync"
6)
7
8func safeGo(wg *sync.WaitGroup, fn func()) {
9wg.Add(1)
10go func() {
11defer wg.Done()
12defer func() {
13if r:= recover(); r!= nil {
14fmt.Println("Hata yakalandı:", r)
15}
16}()
17fn()
18}()
19}
20
21func main() {
22var wg sync.WaitGroup
23
24safeGo(&wg, func() {
25fmt.Println("Goroutine 1 çalışıyor")
26})
27
28safeGo(&wg, func() {
29panic("Goroutine 2'de sorun!")
30})
31
32safeGo(&wg, func() {
33fmt.Println("Goroutine 3 çalışıyor")
34})
35
36wg.Wait()
37fmt.Println("Program başarıyla kapandı")
38}

Çıktı:

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1Goroutine 1 çalışıyor
2Goroutine 3 çalışıyor
3Hata yakalandı: Goroutine 2'de sorun!
4Program başarıyla kapandı

Burada safeGo fonksiyonu, her goroutine'yi defer ve recover ile sarmalıyor. Panic oluşursa yakalanır ve program çökmez. sync.WaitGroup tüm goroutine'lerin bitmesini bekler.

Bir adım öteye gitmek istersen, hataları bir kanal üzerinden ana goroutine'ye gönderebilirsin. Böylece hangi goroutine'de ne hatası olduğunu takip edebilirsin.

1func safeGoWithError(wg *sync.WaitGroup, errChan chan error, fn func()) {
2wg.Add(1)
3go func() {
4defer wg.Done()
5defer func() {
6if r:= recover(); r!= nil {
7errChan <- fmt.Errorf("panic: %v", r)
8}
9}()
10fn()
11}()
12}

Sık yapılan hata: defer recover'ı doğrudan goroutine'nin başına koymak ama panik yığını izini kaybetmek. Hata mesajını loglaman gerekir, yoksa neyin patladığını anlamak zor olur.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz