Furkan KapukayaYazılım geliştirme
Yazılım Mimarisi ve Temiz Kod3 dk okuma

Hata Yönetimi: Exception'ları Doğru Kullanmak

Yazılımda hata yönetiminin temel ilkeleri; exception ne zaman fırlatılır, ne zaman yakalanır, boş catch tehlikesi, global hata yakalama, loglama, kullanıcıya hata mesajı ve Result deseni.

Her yazılım hata ile karşılaşır: ağ kopar, disk dolar, kullanıcı beklenmedik bir değer girer. İyi yazılımı kötü yazılımdan ayıran, hatanın hiç olmaması değil; hatanın doğru yerde yakalanması, anlaşılır şekilde raporlanması ve sistemi tutarsız bırakmamasıdır.

Beklenen hata ile beklenmeyen hata

İki tür durumu ayırmak işin yarısıdır:

  • Beklenen durumlar: Stokta ürün yok, kullanıcı geçersiz e-posta girdi, kayıt bulunamadı. Bunlar iş akışının parçasıdır.
  • Beklenmeyen hatalar: Veritabanına ulaşılamıyor, null referans, dosya bozuk. Bunlar istisnai durumlardır.

Exception mekanizması ikinci grup için tasarlanmıştır. Beklenen durumları exception ile yönetmek kodu hem yavaşlatır hem de okunmasını zorlaştırır.

Altın kurallar

  1. Hatayı yutmayın. Boş bir catch bloğu, sorunu çözmez; gizler.
  2. Yalnızca bir şey yapabileceğiniz yerde yakalayın. Tekrar deneme, alternatif yol, kullanıcıya anlamlı mesaj gibi.
  3. Bağlam ekleyin. "Hata oluştu" yerine "12345 numaralı sipariş faturalanırken entegratör zaman aşımına uğradı".
  4. Orijinal hatayı koruyun. Yeniden fırlatırken throw; kullanın; throw ex; yığın izini (stack trace) kaybettirir.
  5. Kaynakları serbest bırakın. using ile dosya ve bağlantıların her durumda kapanmasını sağlayın.
// Kötü
try { FaturaGonder(siparis); } catch { }

// İyi
try
{
    await faturaServisi.GonderAsync(siparis);
}
catch (HttpRequestException ex)
{
    logger.LogError(ex, "Fatura gönderilemedi. Sipariş: {SiparisId}", siparis.Id);
    await kuyruk.TekrarDenemeyeAlAsync(siparis.Id);
}

Global hata yakalama

Web uygulamalarında her metodu try-catch ile sarmak yerine merkezi bir hata yakalayıcı kullanılır. ASP.NET Core'da bu iş middleware ve IExceptionHandler ile yapılır: beklenmeyen hatalar loglanır, kullanıcıya ise ayrıntı içermeyen standart bir yanıt döner. API'lerde bu yanıt için Problem Details standardı önerilir.

Kullanıcıya ne gösterilmeli?

  • Teknik ayrıntılar (yığın izi, SQL sorgusu, sunucu yolu) asla kullanıcıya gösterilmemelidir; saldırganlara bilgi verir.
  • Mesaj, kullanıcının ne yapabileceğini söylemelidir: "Bağlantı sorunu yaşandı, birkaç dakika sonra tekrar deneyin."
  • Destek için bir hata numarası göstermek, loglarda ilgili kaydı bulmayı kolaylaştırır.

Loglama

Yakalanan her önemli hata, yapılandırılmış ve aranabilir şekilde loglanmalıdır. Ayrıntılar: .NET'te loglama ve gözlemlenebilirlik.

Result deseni

Beklenen hatalar için bazı ekipler exception yerine sonucu açıkça döndüren bir yapı kullanır:

public Result<Siparis> SiparisOlustur(SepetDto sepet)
{
    if (sepet.Kalemler.Count == 0) return Result.Hata("Sepet boş.");
    // ...
    return Result.Basarili(siparis);
}

Bu yaklaşım, çağıranı hatayı ele almaya zorlar ve akışı okunur kılar.

Sık sorulan sorular

Her metoda try-catch eklemeli miyim?

Hayır. Yakalayıp anlamlı bir şey yapamayacağınız yerde hatayı yukarı bırakın; merkezi hata yakalayıcı onu loglayacaktır.

Kendi exception sınıflarımı yazmalı mıyım?

İş kurallarına özgü ve farklı ele alınması gereken durumlar için evet; ama her hata için yeni bir tür oluşturmak gereksizdir.

Sonuç

Hata yönetimi, yazılımın kötü günde nasıl davrandığını belirler. Hataları yutmayan, bağlamla loglayan ve kullanıcıya anlaşılır mesaj veren bir yapı; destek maliyetini düşürür ve güveni artırır.