Hata Yakalama ve Iskalama Kültürü
Mike Hodlow‘un başlığını Fight Club’tan esinlendiği “Hata Yakalamanın İlk Kuralı: Hatayı Yakalama!” yazısı, programlamada bir “exception handling” yani Türkçesiyle “hata yakalama” kültürünün olduğunu ve programcı/yazılımcı etiketindeki kimselerin de bu kültüre mutlaka aşina olması gerektiğini bizlere tekrar hatırlatıyor.
Yıllar evvel bir programlama kitabında hatalardan “istisna” olarak bahsedildiğini görmüş ve bu kavramı kendime uzak bulmuştum. İstisnalar hem kaideyi bozar hem keyfi kaçırırdı.
Ancak zaman içinde anladık ki bir programcının bilmesi gereken şey aslında her insanın bilmesi gereken şey. Hayatta hata yapmak, yapmamak kadar doğaldır. Bir programın akışında hatalar oluşması da oluşmaması kadar olağan. Ve bu hatalar, her seferinde farklı sebeblerden ortaya çıkabilir. Bir hata, başka hatalardan silsile yoluyla gelmiş olabilir (Bir exception var exception’dan içeri).
Evet, hatalar ne kadar normal dediysek yazıyı bu şekilde bitirip gideceğimizi sanmayınız. Anormal olanı demeden gitmeyiz.
Anormal olan şey, hatayı hesaba katmamaktır veya hataya karşı lakayıt kalmaktır. Bir program kodu, hataya yol açabilecek durumlar akılda tutularak yazılmalıdır. Yazılmamışsa bile geri dönüp refactor edilmelidir. Akılda tutulmuşsa bile formaliteden değil yerinde müdaheleler yapılmalıdır.
Hata yakalama ile ilgili şu altın prensipler, umarım programcı arkadaşlarımız için faydalı olacaktır.
Geliştirdiğimiz yazılımlarda üç tip hata oluşabilir:
- Programlamadan (sizden) doğan hatalar
- İstemciden doğan hatalar
- Kaynaklardan doğan hatalar
Peki, nedir bu hataların detayları?
- Programlama hataları ölümcül hatalardır. Programınız çakılır, devam edemez. Bir bug‘ınız vardır ve siz çözene kadar öyle duracaktır.
- İstemciden doğan hatalar daha çok doğrulamadan(validation) kaynaklanan hatalar şeklinde yorumlanır. Örneğin kullanıcının size girdiği sayı, alfanumerik karakterler içeriyorsa bir ihlal vardır. Veya gönderdiği bir XML dosyası elinizdeki şemaya göre valid değildir. Kodunuzdaki doğrulama koşullarını dikkatli şekilde ele almanız, bu tip hataları hiçbir şekilde ıskalamamanız ve yakalamanız gerekir.
- Kaynaklar, kullanıcı ile aranıza giren üçüncü şahıslardır. Örneğin bellek dolmuştur, diskte yer kalmamıştır veya network bağlantısı gitmiştir. Bu tür durumları da titizlikle yakalayıp, ayırt edip mantıklı ve anlaşılır mesajlarla kullanıcıyı bilgilendirme lazımdır.
- Genel Exception sınıfları yerine özelleşmiş Exception sınıfları yakalanmalıdır. .NET için konuşursak, System.Exception denen hataların babası, sadece tek bir noktada ve global olarak yakalanmalıdır. Try/catch içerisinde yakalanan hatalar öncelikle özgün hata tipleri(FormatException, InvalidOperationException…) ele alınacak şekilde kurgulanmalı ve en son aşamada(yani son catch bloğunda) System.Exception tipine göre işlem yapılmalıdır. Kimse hatadan anlamadıysa, en son noktada yakalanmalı, log’lanmalı ve mağrur bir şekilde kullanıcıya işlemin devam edemediği bildirilmelidir.
- Mantıksal akışlar Exception’lara göre kurgulanmamalıdır. Bu yapılar “iş” amaçlı değildir.
- Herkesin çok ihlal ettiği kural: Exception’ların StackTrace‘i yutulmamalıdır. Eğer catch’lerde yakalayıp “bu yoluna devam etsin” dediğiniz hatalar olur ise onları mutlaka throw ile gönderiniz; eğer throw new ile gönderirseniz o zor bulunan, kimi zaman değerine paha biçilmeyen Stack Trace sıfırlanmış olacaktır. Özetle throw new çok dikkatle kullanılması gereken bir kalıptır, istisnai durumlarınız yoksa throw kullanın. Stack Trace muhafaza edilmesi gereken değerli bir madendir.
- OOP mevsimine aldanıp yeni nesil Exception tipleri icad etmek yerine sistemin sizin için sunduğu öntanımlı olanları kullanınız. Buyurun size .NET dünyasının exception sınıfları ve Java dünyasının exception sınıfları. Farklı bir dil kullanıyorsanız o dile özel exception sınıflarını arama motorlarından veya SDK’lardan mutlaka bakın.
- Exception’lar çalıştıkları runtime’lar için pahalı ve ağır lokmalardır. O nedenle mümkün olduğunda onlara bulaşmadan adımlamak lazımdır. Bunu yapmanın en güzel yolu da pattern’lere yani kullanım kalıplarına başvurmaktır.
- Dokümantasyon: Her işimizi belgeli yapmalıyız. Kullandığınız programlama araçları(.NET, Java vb.) kodlarınıza eklediğiniz yorumlara bir metot kullanıldığında hangi exception tiplerinin fırlatılabileceğini de belirtmenize olanak sağlamaktadır. Bu da yazdığınız metotları kullanacak başka yazılımcılara “tedbirini al, buradan sana X exception’ı fırlatılabilir…” uyarısı anlamına gelecektir.
- Buraya kadar saydıklarımız işinize yaramıyorsa bir de “Best Practices for Exceptions” yazılarına bir göz atın derim. Misal şuradan başlayabilirsiniz
Dışarıdan bakınca basit görünen, detayına girince de çok dikkat edilmesi gereken bir husustur exception handling. Umarım faydası olacak birkaç noktaya birlikte bakma fırsatı bulmuşuzdur.