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
- Hatayı yutmayın. Boş bir
catchbloğu, sorunu çözmez; gizler. - Yalnızca bir şey yapabileceğiniz yerde yakalayın. Tekrar deneme, alternatif yol, kullanıcıya anlamlı mesaj gibi.
- Bağlam ekleyin. "Hata oluştu" yerine "12345 numaralı sipariş faturalanırken entegratör zaman aşımına uğradı".
- Orijinal hatayı koruyun. Yeniden fırlatırken
throw;kullanın;throw ex;yığın izini (stack trace) kaybettirir. - Kaynakları serbest bırakın.
usingile 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.