Exception tasarımı: hataları katmanlara göre yönetmek
Beceri rehberi

Exception tasarımı: hataları katmanlara göre yönetmek

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

Hata yönetimi stratejisi nasıl kurulur: hata türlerini ayırma, özel exception sınıfları, katmanlar arası çevirme, loglama ve sık yapılan hatalar.

Hata yönetimi try-catch yazmaktan fazlası

Hata yönetimi, bir sistemde işlerin ters gitmesine önceden karar vermiş olmaktır. Hangi hata kullanıcıya gösterilir, hangisi yalnızca loga yazılır, hangisinde işlem geri alınır, hangisinde yeniden denenir? Bu sorulara kodu yazmadan önce yanıt verilmezse her geliştirici kendi alışkanlığını koda taşır ve uygulama genelinde tutarsız bir davranış ortaya çıkar.

İyi tasarlanmış bir hata yönetimi şunları sağlar: hatanın nerede ve neden oluştuğu anlaşılır, çağıran kod hataya göre doğru karar verebilir, kullanıcı ise sistemin iç ayrıntılarını görmeden anlamlı bir mesaj alır. Exception tasarımı bu hedeflerin kod tarafındaki karşılığıdır.

Önce hata türlerini ayırın

Her hata aynı muameleyi hak etmez. Pratikte işe yarayan ayrım şudur: • Doğrulama hataları: kullanıcının ya da çağıran kodun verdiği girdi geçersizdir. Düzeltilebilir, kullanıcıya anlatılmalıdır. • İş kuralı hataları: girdi biçim olarak doğrudur ama kural izin vermez, örneğin yetersiz bakiye ya da kapanmış bir sipariş. Beklenen durumdur, çoğu zaman exception yerine açık bir sonuç nesnesiyle de ifade edilebilir. • Altyapı hataları: veritabanı, ağ ya da dış servis erişilemiyor. Geçici olabilir, yeniden deneme uygundur. • Programlama hataları: boş referans, dizi sınırı aşımı gibi kodun kendi hatası. Yakalayıp yutmak yerine görünür biçimde patlamalı ve loglanmalıdır.

Bu ayrım, hangi hatayı yakalayacağınızı ve yakaladığınızda ne yapacağınızı belirler. Tek bir genel Exception yakalayıp ekrana aynı mesajı basmak, birbirinden farklı durumları tek davranışa indirger.

Özel exception sınıfı ne zaman ve nasıl yazılır?

Özel exception sınıfı, çağıran kodun hatayı türüne göre ayırt etmesi gerektiğinde yazılır. Mesaj metnini ayrıştırarak karar vermek kırılgandır; tür üzerinden karar vermek ise derleyici ya da test tarafından korunabilir.

Tasarım ilkeleri şunlardır: uygulamanın kök hata sınıfını tanımlayın, diğerleri ondan türesin. Sınıf adı olayı anlatsın, kullanıcı mesajı ile teknik ayrıntı ayrı tutulsun. Hatanın kök nedeni zincirleme olarak taşınsın ki orijinal iz kaybolmasın. Bağlam bilgisini (hangi kayıt, hangi kullanıcı, hangi işlem) alan olarak ekleyin.

Örneğin Python benzeri bir dilde:

class UygulamaHatasi(Exception): pass

class IsKuraliHatasi(UygulamaHatasi): def __init__(self, kural, mesaj): super().__init__(mesaj) self.kural = kural

class AltyapiHatasi(UygulamaHatasi): pass

Her ayrıntı için ayrı sınıf açmak da tuzaktır. Çağıran kod bu hataları farklı ele almayacaksa tek sınıf ve bir alan yeterlidir.

Hatayı yakalamak mı, yukarı bırakmak mı?

Altın kural: hatayı yalnızca onunla anlamlı bir şey yapabilecek katmanda yakalayın. Anlamlı iş; yeniden denemek, varsayılan değere düşmek, işlemi geri almak ya da hatayı daha anlamlı bir türe çevirmektir. Yalnızca loga yazıp aynı hatayı yeniden fırlatmak, aynı hatanın her katmanda tekrar loglanmasına yol açar ve log kalabalığı yaratır.

Katmanlar arasında çeviri yapın. Veri erişim katmanındaki bir veritabanı sürücüsü hatası, iş katmanına olduğu gibi sızmamalıdır; iş katmanı bunu kendi AltyapiHatasi türüne sararak yukarı iletir ve kök nedeni zincirde taşır. Böylece iş katmanı bir veritabanı sürücüsünün ayrıntısını bilmek zorunda kalmaz, sürücüyü değiştirdiğinizde üst katmanlar etkilenmez.

Boş bir catch bloğu en tehlikeli kalıptır. Hata yutulur, sistem tutarsız durumda devam eder ve sorun saatler sonra bambaşka bir yerde belirir.

Kullanıcı mesajı, log ve izlenebilirlik

Aynı hatanın iki ayrı okuru vardır: kullanıcı ve geliştirici. Kullanıcıya ne olduğunu ve ne yapabileceğini söyleyen sade bir mesaj gösterilir; yığın izi, sorgu metni, sunucu adı gibi ayrıntılar gösterilmez, çünkü bunlar hem anlamsızdır hem güvenlik riskidir. Geliştiriciye ise tam bağlam gerekir: hata türü, kök neden, istek kimliği, ilgili kayıt, zaman damgası.

Bunu sağlamanın pratik yolu, uygulamanın en dış sınırında tek bir merkezi hata işleyicisi kurmaktır. Web uygulamasında bu bir ara katman ya da global filtre olur; işleyici hata türüne bakar, uygun durum koduyla kullanıcı yanıtını üretir ve ayrıntıyı tek seferde loglar. Her istekte üretilen bir korelasyon kimliğini hem yanıta hem loga yazarsanız destek ekibi kullanıcının bildirdiği hatayı log içinde dakikalar yerine saniyelerde bulur.

Parolalar, kart bilgileri ve kişisel veriler log mesajlarına girmemelidir. Hata nesnesine bağlam eklerken bu alanları baştan dışarıda bırakın.

Sık yapılan hatalar ve kontrol listesi

Ekiplerde en sık görülen sorunlar şunlardır: • Genel Exception yakalayıp hiçbir şey yapmamak ya da yalnızca yazdırmak • Hata kodlarını ve null dönüşlerini exception ile karıştırmak; aynı projede birbirinden farklı hata dilleri bulunması • Akış kontrolü için exception kullanmak: beklenen, sık gerçekleşen durumlar için exception fırlatmak hem okunabilirliği hem performansı bozar • finally ya da eşdeğer temizlik bloğunu unutmak; dosya, bağlantı ve kilit gibi kaynakların hata anında serbest kalmaması • Hata mesajına kullanıcı verisi ya da gizli bilgi sızdırmak • Hata yollarını test etmemek: mutlu yol testleri geçer, ama hata durumunda ne olduğu hiç denenmemiştir

İnceleme sırasında kendinize şu soruları sorun: Bu hata kim tarafından, hangi kararı vermek için yakalanıyor? Orijinal neden korunuyor mu? Kaynaklar her durumda serbest kalıyor mu? Kullanıcı ne görüyor, geliştirici ne görüyor? Hata yolu için en az bir test var mı?

Öğrenme yolu ve Mindset'te nerede çalışılır?

Başlangıç aşamasında kendi dilinizin exception mekanizmasını, try-catch-finally akışını ve standart hata türlerini öğrenin. Sonra küçük bir projede hata türlerini ayırıp kendi hata hiyerarşinizi çıkarın. İleri aşamada merkezi hata işleyici, yeniden deneme ve zaman aşımı politikaları, dağıtık sistemlerde hata yayılımı gibi konulara geçin.

Mindset'in Temiz Kod (Clean Code) Prensipleri programı, nesneler, veri yapıları ve hata yönetimini tek modülde ele alır; Clean Coding Uzmanlığı Eğitimi ise Hata Yönetimi ve İstisna İşleme başlıklı ayrı bir modül içerir. İkisi de kod kalitesini ekip standardına dönüştürmek isteyen yazılım geliştiriciler ve kod inceleme yapan kıdemli mühendisler için uygundur; ekip içinde ortak bir hata yönetimi sözleşmesi çıkarmak isteyen kurumsal geliştirme ekipleri de bu içeriği referans alabilir.

İlgili Mindset programı

Temiz Kod (Clean Code) Prensipleri

Sık sorulanlar

Sık sorulan sorular

Exception mı fırlatmalıyım yoksa hata kodu mu döndürmeliyim?

Beklenmeyen ve çağıranın normal akışta ele alması gerekmeyen durumlar için exception uygundur. Sık gerçekleşen, beklenen sonuçlar için (örneğin kayıt bulunamadı) açık bir sonuç nesnesi daha okunaklıdır. Önemli olan projede tek bir tutarlı yaklaşım seçmek ve iki dili karıştırmamaktır.

Genel Exception yakalamak her zaman yanlış mı?

Hayır. Uygulamanın en dış sınırında, beklenmeyen hataları loglayıp kullanıcıya güvenli bir yanıt dönmek için genel yakalama gerekir. Yanlış olan, iç katmanlarda her şeyi yakalayıp yutmaktır; çünkü orada hatayla anlamlı bir iş yapamazsınız ve sorunu gizlersiniz.

Hatayı kaç katmanda loglamalıyım?

İdeal olarak bir kez, hatanın nihai olarak ele alındığı yerde. Her katmanda loglayıp yeniden fırlatmak aynı olayın tekrar tekrar kaydedilmesine yol açar ve gerçek sorunu bulmayı zorlaştırır. Kök nedeni zincirde taşıyıp merkezi işleyicide yazmak daha temizdir.

Hata yönetimi performansı etkiler mi?

Exception fırlatmak çoğu dilde normal akıştan pahalıdır, bu yüzden sık ve beklenen durumlar için kullanılmamalıdır. Gerçekten istisnai durumlarda maliyet kabul edilebilir; asıl risk performans değil, hataların yutulması ya da yanlış katmanda ele alınmasıdır.

Hata yollarını nasıl test ederim?

Bağımlılıkları taklit eden testlerle veritabanı erişilemiyor, dış servis zaman aşımına uğruyor gibi durumları zorlayın. Örneğin bir dış servis çağrısında zaman aşımı simüle edip kullanıcıya genel bir hata mesajı gösterildiğini, ayrıntının yalnızca log'a yazıldığını kontrol edin. Beklenen exception türünün fırlatıldığını, kaynakların serbest kaldığını ve kullanıcıya doğru yanıtın döndüğünü doğrulayın.

Yazılımda Hata Yönetimi ve Exception Tasarımı