Giriş

Modern yazılım projelerinde hata yönetimi (exception handling), kodun güvenilirliği, bakımı ve sürdürülebilirliği için en önemli yapı taşlarından biridir. Doğru yapılan hata yönetimi, hataların izlenebilirliğini artırır, kodun test edilebilirliğini yükseltir ve kullanıcı deneyimini iyileştirir. Yanlış yapıldığında ise “gizli bug’lar”, yutulan hatalar ve “asla çözülmeyen” prod ortamı sorunlarıyla boğuşursun.

1. Exception Handling Nedir?

Exception handling, çalışma zamanında oluşabilecek beklenmeyen hataları yakalamak, yönetmek ve gerektiğinde mantıklı bir aksiyon almak için kullanılan yapıdır.

C#’ta anahtar kavramlar:

  • try, catch, finally blokları
  • Exception türleri (System.Exception, ArgumentException, NullReferenceException, vs.)
  • Fırlatma (throw) ve zincirleme (rethrow)

2. Exception Handling Temel Akışı

Diyagram: Exception Handling Akışı

  1. Kod try bloğu içinde çalışır.
  2. Hata oluşursa, uygun catch bloğu devreye girer.
  3. finally bloğu ise hata olsa da olmasa da çalışır (örn. kaynak serbest bırakma).

3. Kötü (Yanlış) Kullanım Örnekleri

1. Exception “Yutmak”

try
{
    // ...
}
catch
{
    // Hiçbir şey yapılmıyor, hata sessizce yutuldu!
}

2. Gereksiz Genel Catch

try
{
    ProcessOrder();
}
catch (Exception ex)
{
    Console.WriteLine("Bir hata oluştu.");
    // Ne hatası? Kayıt yok, detay yok, iz yok!
}

3. Tüm Uygulamada Hiç Catch Kullanmamak

  • Hata kontrolsüz yükselir, uygulama patlar, hiçbir log yok.

4. Exception ile Akış Kontrolü

try
{
    return list[index];
}
catch (Exception)
{
    return null; // Exception handling “if” yerine kullanılmaz!
}

4. Doğru Kullanım ve Modern Yaklaşımlar

1. Spesifik Exception Yakalama

try
{
    File.ReadAllText("dosya.txt");
}
catch (FileNotFoundException ex)
{
    Log.Error($"Dosya bulunamadı: {ex.Message}");
}
catch (UnauthorizedAccessException ex)
{
    Log.Error($"Erişim izni yok: {ex.Message}");
}

2. Exception’a Anlamlı Aksiyon

try
{
    SaveToDatabase();
}
catch (DbUpdateException ex)
{
    NotifyAdmin(ex);
    Log.Error(ex, "DB güncelleme hatası!");
    throw; // Zincirleme, hatayı üst kata fırlat.
}

3. Finally Bloğunda Kaynak Yönetimi

FileStream fs = null;
try
{
    fs = File.Open("data.txt", FileMode.Open);
    // ...
}
finally
{
    fs?.Dispose();
}

4. Using ile Otomatik Kaynak Yönetimi

using (var fs = File.Open("data.txt", FileMode.Open))
{
    // Dosya otomatik dispose edilir
}

5. C# ile Gerçek Senaryolar

1. API Katmanında Exception Handling

[HttpGet]
public IActionResult GetProduct(int id)
{
    try
    {
        var product = _service.GetProduct(id);
        if (product == null)
            return NotFound();
        return Ok(product);
    }
    catch (Exception ex)
    {
        Log.Error(ex, "GetProduct exception");
        return StatusCode(500, "Sunucu hatası");
    }
}

2. Async/Task Exception Handling

try
{
    await ProcessAsync();
}
catch (CustomException ex)
{
    Log.Error(ex, "Asenkron işlem hatası");
}

3. Validation ve Domain Exception

public void RegisterUser(string email)
{
    if (string.IsNullOrWhiteSpace(email))
        throw new ArgumentException("Email zorunlu!");

    // Devam...
}

6. Özel Exception Sınıfları

Kendi iş kuralına veya domain’ine özel exception tanımlayabilirsin.

public class UserAlreadyExistsException : Exception
{
    public UserAlreadyExistsException(string email)
        : base($"Kullanıcı zaten kayıtlı: {email}") { }
}

Kullanım:

if (userRepository.Exists(email))
    throw new UserAlreadyExistsException(email);

7. Global Exception Handling

Modern projede her catch’e log yazmak yerine merkezi bir global exception handler önerilir.

.NET Core Middleware ile

public class ExceptionMiddleware
{
    private readonly RequestDelegate _next;
    public ExceptionMiddleware(RequestDelegate next) => _next = next;

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            Log.Error(ex, "Global exception");
            context.Response.StatusCode = 500;
            await context.Response.WriteAsync("Bir hata oluştu.");
        }
    }
}

// Startup.cs
app.UseMiddleware<ExceptionMiddleware>();

8. Exception Handling’in Avantaj ve Dezavantajları

Avantajlar

  • Hataları anlamak, takip etmek ve çözmek kolaylaşır.
  • Kullanıcıya anlamlı ve kontrollü mesaj gösterilir.
  • Kodun farklı katmanlarında log, bildirim, aksiyon koyabilirsin.
  • Kaynak yönetimi kolaylaşır (using/finally).

Dezavantajlar

  • Fazla ve gereksiz try/catch blokları kodu şişirebilir.
  • Exception yutulursa hatayı izlemek imkansızlaşır.
  • Performans olarak, akış kontrolü için exception kullanmak pahalıdır.

9. Sık Yapılan Hatalar

  • Exception’ı yutmak, log atmamak
  • Tüm hataları genel Exception ile yakalamak, spesifik olmamak
  • Try/catch’i fazla veya yanlış yerde kullanmak
  • Exception ile program akışını kontrol etmeye çalışmak
  • Asenkron kodda exception handling’i unutmak
  • Hatalı/eksik log ile hata izinin kaybolması
  • Global handler olmadan her yerde ayrı ayrı try/catch kullanmak

10. En İyi Uygulamalar & İpuçları

  • Her zaman mümkün olan en spesifik exception’ı yakala.
  • Exception yakalandığında mutlaka log kaydı bırak.
  • Finally/using ile kaynak yönetimini unutma.
  • “Throw;” ile zincirleme yap, hatayı üst katmana fırlatmayı ihmal etme.
  • Try/catch bloklarını en küçük, mantıklı kapsamda tut.
  • Validation ve domain hataları için özel exception sınıfları kullan.
  • Web projelerinde global exception handler uygula (middleware/filter).
  • Exception mesajlarına gizli/güvenlik verisi koyma.
  • Unit testlerde exception fırlatan senaryoları da kapsa.

11. Tablo & Diyagram

Sık Kullanım Tablosu

Hatalı Kullanım Doğru Kullanım
catch { } catch (SpesifikException ex) { Log… }
catch (Exception) { } catch (ArgumentNullException ex) { }
try/catch her yerde Global handler + önemli yerde try/catch
try ile akış kontrolü if/else, null kontrolü kullan
Hata log yok Log, bildirim, takip ekle

12. SSS – Sıkça Sorulan Sorular

Exception handling performansı düşürür mü?
Exception fırlatmak pahalıdır, akış kontrolü için kullanılmamalıdır.

Sadece Exception ile mi yakalamalıyım?
Hayır, mümkünse spesifik exception yakalamalısın.

Log tutmak şart mı?
Evet, özellikle prod ortamında hatasız log takip imkansızdır.

Her yerde try/catch gerekir mi?
Hayır, mantıklı kapsamda, gereksiz çoğaltma kodu şişirir.

Kendi exception’ımı yazmalı mıyım?
Eğer domain’e özgü, iş mantığı özel bir hata varsa evet.

13. Sonuç & Pratik Özet

  • Exception handling, kodun sağlamlığı ve izlenebilirliği için zorunludur.
  • Kapsamı dar, spesifik ve log tutan try/catch blokları kullan.
  • Exception ile akış kontrolü yapmaktan kaçın.
  • Merkezi/global hata yönetimi uygula.
  • Asenkron kodda da exception handling’i unutma.
  • Sık yapılan hatalardan kaçın, kodunu test et ve izle.

14. Kaynaklar

By tanju.bozok

Software Architect, Developer, and Entrepreneur

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir