HATA YAKALAMA (TRY-CATCH-FİNALY) – Ahmet Cansever
Perşembe , 30 Mart 2017
Anasayfa » C# » HATA YAKALAMA (TRY-CATCH-FİNALY)

HATA YAKALAMA (TRY-CATCH-FİNALY)

Program çalışırken hemen hemen her aşamasında hatalar meydana gelebilir. Kod parçalarının her zaman beklenildiği gibi çalışacağından emin olmak oldukça zordur.
Bu hatalar kişiden kaynaklanabileceği gibi kişinin dışından da kaynaklanabilir.

Bilgisayara bir program kurulduğu düşünülsün. Çok gerekli bir program olsa da sürekli programda hatalarla karşılaşılırsa ne kadar gerekli olursa olsun, bir daha bu program kullanılmak istenilmez. Oysa programın hataları giderilmiş, hata verdiğinde hatanın nedeninin ne olduğu söyleniyorsa elbette ki bu programı kullanmak kişiye daha yakın gelecektir. O nedenle de hataların programdan ayıklanması son derece önemlidir.

Try- Catch Bloku

Hataları yakalamadan bir program yazılarsa yukarıda da açıkça belirttiğimiz gibi insanlar bu programı kullanmak istemez. Aşağıdaki örnek, hataların bir programı ne hâle getirdiğine çok güzel bir örnektir.

Örnek: Klavyeden girilen iki sayıyı toplayıp sonucu ekrana yazan kodlama yapılmalıdır.

Programın form görüntüsü aşağıdaki gibi olsun.


Programın çalışması şu şekilde olacaktır: İki sayı girilecek ve “Topla” butonuna tıklandığında “Sonuç” bölümünde iki sayının toplamı çıkacaktır. Örneğin kullanıcı ilk sayıyı girdi fakat ikinci sayıyı girmedi. Normal olarak düşünüldüğünde ikinci sayı otomatik sıfır olmalıdır. Dolayısıyla da “Sonuç” bölümünde ilk sayı görünmelidir. Böyle bir durumda yazılan program bu resimde göründüğü gibi bir hata ile karşılaşacaktır.

İkinci sayı girilmediğinde topla butonuna basıldığında ekran görüntüsü şu şekilde olacaktır.


Oysa bu gibi durumlarda ya kullanıcı ikinci sayıyı girmesi içinde uyarılmalı ya da ikinci sayı otomatik olarak sıfır alınmalıdır. Bu gibi işlemler yapılırsa hem programın olur olmadık yerde kesilmesinin önüne geçmiş hem de kodun daha da profesyonel olması sağlanmış olunur. trycatch bloku ile kodu daha sağlam bir zemine oturtulabilir ve programın kullanılabilirliği artırılmış olunur.

Try-catch ifadesinin söz dizimi aşağıdaki gibidir:

Try

{

Hata olmadığı sürece çalışacak kodlar;

}

Catch (özel durum)

{

Hata oluştuğunda çalışacak kodlar;

}

Yukarıdaki söz dizeminde görüldüğü gibi normal kodları try bölümüne, herhangi bir hata oluştuğunda ise bu gibi durumları yakalamak için de catch bölümüne yazılmalıdır. Buradaki özel durum ise hatanın nedenini yakalamak için kullanılan bir ifadedir.

Öyleyse hataların önüne geçmek için try-catch yapısını aşağıdaki örnekte inceleyelim.


Böylece program kodu hatalara karşı bir öncekine göre daha sağlam bir yapıya kavuşmuş oldu. Resimdeki kodlamada görüldüğü gibi programın normal kodlaması try bölümüne, hata oluştuğunda çalışması gereken kısım ise catch bölümüne yazılmıştır. Catch bölümünde oluşan özel durumu yakalamak içinse Exception (özel durum) türünde hata ifadesi tanımlanmıştır. Oluşan özel durum ile ilgili her türlü bilgi bu ifadeye atanmış olacaktır.

Bu ifadede Resimde görüldüğü gibi label6 kontrolüne aktarılmaktadır. Programın çalışmasında aşağıda görüldüğü gibi olacaktır.


Yukarıdaki resimde görüldüğü gibi program ikinci sayı girilmemesine rağmen rastgele kesilmemiş ve kullanıcıya oluşan hatanın nedeni bildirilmiştir.

Aynı zamanda oluşan hatayı messageBox ile de gösterebiliriz.


Programın çalışmasında aşağıda görüldüğü gibi olacaktır.


Birden Çok Catch Bloku

.NET Platformu tarafından sağlanan özel durum kütüphanesi oldukça kapsamlıdır. .NET Platformunda birçok özel durum tanımlanmıştır ve yazılan herhangi bir programda bu özel durumlarla karşılaşma oranı son derece yüksektir. Örneğin, yazılan bir programda metinsel veriyi sayısal bir veriye dönüştürme özel durumu ile karşılaşılabilir. Bunun yanında int16 veri türüne sahip bir değişkene int32 kapsamındaki bir veriyi (overflow, taşma hatası) atama gibi bir özel durumla da karşılaşılabilir. Bunun gibi daha birçok özel durumla karşılaşma durumu söz konusudur.

Karşılaşılan her bir özel durum için ayrı ayrı try-catch bloku yazmak elbette son derece mantıksızdır. Bunun yerine aynı try-catch blokunda farklı catch bölümler kullanılabilir.

Birden çok catch bloku için söz dizimi aşağıdaki gibidir:

Try

{

Hata olmadığı sürece çalışacak kodlar;

}

Catch (özel durum – 1)

{

İlgili hata oluştuğunda çalışacak kodlar;

}

Catch (özel durum – 2)

{

İlgili hata oluştuğunda çalışacak kodlar;

}

En sık kullanılan üç özel durum aşağıda yer almaktadır.

FormatException: Sayısal veri türüne sahip bir değişkene bir harf girilmesi veya atanması.

OverflowException: Bir değişkene atanan veya girilen sayı, değişkenin tanımlandığı veri türünün alabileceği aralığın dışında kalması.

ArgumentNullException: Sayısal veri türüne sahip bir değişkene null değerini atamak.


Yukarıdaki resimde görüldüğü gibi her bir özel durum için ayrı catch blokları kullanılmıştır. Her özel durum içinde kullanıcı ayrı uyarılmıştır. Bu kod çalıştırıldığında aşağıdaki resimdeki gibi bir ekran çıktısı ile karşılaşılır.



Resim ‘de görüldüğü gibi “Birinci Sayı” alanına int16 veri türünden daha büyük bir sayı girildiği için overflow hatası oluşmuştur. Kodlamada da bu hata yakalandığı için ekrana “HATA! Alanlara çok büyük sayılar giriyorsunuz…” şeklinde uyarı gelmektedir.

Akla şu şekilde bir soru gelebilir: “Her iki özel durumda aynı anda meydana gelirse hangisi çalışacaktır?” Kodlamada ilk olarak bulunan catch bloku devreye girecektir.

Denetlenmiş İfadeler

Belirtilen sınırların dışında bir sayıyı int türünde bir değişkende tutmak istersek taşma meydana gelir. Eğer -2.147.483.648 sayısından daha küçük bir sayı tutulmak istenirse underflow, 2.147.483.647 sayısından büyük bir sayı tutulmak istenirse overflow durumu oluşur. Genel olarak her iki durum da overflow olarak adlandırılmaktadır. Varsayılan olarak programlama dili derleyicisi taşma problemlerinde yanlış değer üreten bir yapıya sahiptir.


Böyle bir kodlama çalıştırıldığında aşağıdaki ekranda yer alan veriler girilerek “Hesapla” butonuna tıklanır.


Normalde resimde sayıların çarpılması sonucu 100000000000 sonucu oluşması gerekirken 1215752192 sonucu oluşmuştur. İşte burada bir taşma meydana gelmiştir. Bu taşmanın önüne geçmek için iki seçenek mevcuttur. Bunlardan ilki programlama dilinin derleyicisini projelerdeki taşma problemlerine karşı etkin hâle getirerek yanlış sonuç üretmesi yerine hata ile kesilmesi sağlanabilir. İkinci seçenek ise checked ifadesiyle kodlama esnasında bu işlemi yapmaktır.

İlk seçenek için şu adımlar uygulanır: Programda Project menüsünden Projeniz Properties seçeneği seçilir (Projeniz, projenin adıdır.). Proje özellikleri iletişim kutusunda, Build sekmesi tıklanır. Sayfanın sağ alt köşesindeki Advanced düğmesi tıklanır. Advanced Build Settings iletişim kutusunda, Check for arithmetic overflow/underflow onay kutusu işaretlenir. Bundan böyle projeniz taşma problemine karşı etkin hâle gelmiş olacaktır.

İkinci seçenek ise bu işi kodlamayla gerçekleştirmektir. Eğer proje özeliklerindeki Check for arithmetic overflow/underflow seçeneği işaretli değilse ve programın yanlış değer üretmesi istenmiyorsa bu durumda checked ifadesi kullanılmalıdır. Şimdi resimde yer alan kodlamayı aşağıdaki resimde görüldüğü gibi yeniden yapılır.


Resimde yer alan kodlamaya göre programın çalışması esnasında checked blokunda yer alan aritmetiksel işlemde taşma olduğunda, program hata verecektir. Burada yapılan şudur: Programdaki bazı kodlar, oluşabilecek taşmalardan dolayı hatalı sonuçlar üretilmesinin önüne geçilmiştir. Şimdi tekrar program çalıştırılır ve Resimde girdiğiniz değerler tekrar girilir. Programın kesilerek hata verdiği görülecektir. Eğer programın hata sırasında kesilmesi istenmiyorsa try-catch bloku kullanılarak hata yönetilebilir.

Bazı durumlarda ise programın taşma hatası vermesi yerine, ne olursa olsun bir sonuç üretmesi sizin için önemli olabilir. Böyle bir sonucu almak için proje özelliklerindeki Check for arithmetic overflow/underflow seçeneğinin seçili olmaması gerekmektedir. Eğer bu seçenek seçili ise bu durumda unchecked ifadesi ile yanlışta olsa bir sonuç alınabilir. Resimde yer alan kodlardaki aritmetiksel işlemde, oluşan taşmadan dolayı hata aldığınızı düşünerek bu hatanın alınmamasını sağlayabilirsiniz. Aritmetiksel işlemi unchecked ifadesi ile denetim dışına çıkararak bu işlemi gerçekleştirebilirsiniz. Şimdi Resimdeki kodu aşağıdaki şekilde yeniden yazınız.


Resimde görüldüğü gibi kodlamadaki aritmetiksel işlem denetim dışı bırakılmıştır. Böylece aritmetiksel işlemde meydana gelebilecek bir taşmada program hata vermeyecek, yanlış da olsa bir sonuç üretecektir.

Denetlenmiş Deyimler

Checked ve Unchecked ifadelerini, parantez içinde yazılmış bir tam sayı deyiminin başında kullanarak bu tür deyimlerdeki taşma denetlemek için de kullanılabilir.


Yukarıdaki resimdeki kodlama yazıldıktan sonra çalışmasının bir önceki kodlamadan herhangi bir farkının olmadığı görülecektir. Burada da aynı şekilde parantez içinde olan aritmetiksel işlem sonucu oluşacak taşmalar, denetimli hâle gelmiş olmaktadır. Aynı şekilde bir önceki kodlama da aşağıdaki kodlamayla aynı görevi görmektedir. Bu kodlamayı yaparken proje özelliklerinde yer alan Check for arithmetic overflow/underflow seçeneğinin seçili olması gerekmektedir.


Resimdeki kodlamada yer alan çarpma işlemi artık denetimsiz hâle gelmiştir. Dolayısıyla çalışma anında işlem sonucunda herhangi bir taşma meydana geldiğinde program hata vermeyecek, sonuç yanlış da olsa işlem devam edecektir.

Checked ve unchecked ifadeleri, tam sayı olmayan aritmetiksel işlemleri denetlemek için kullanamazsınız. Bu ifadeler sadece int ve long veri türleri için kullanılabilir.

Özel Durumlar

Programlama dili, programınızın çalışması esnasında oluşabilecek hatalara karşı pek çok özel durum içermektedir. Birçok durumda bu özel durumlardan birinin özel duruma uygun olduğu görülecektir. Örneğin, “Denetlenmiş Deyimler” bölümünde sayısal işlemlerde meydana gelebilecek taşmalardan konusu geçmişti veya “Birden Çok Catch Bloku” başlıklı bölümde FormatException hatasından bahsedildi. Bu gibi hatalar sistem tarafından tanınan hatalardır. Ancak bazı programlarda belirlenebilecek özel durumlar oluşabilecektir. Bu gibi özel durumlar içinde programlama dili kendi içerisinde pek çok özel durum kullanıma sunulmaktadır.

Örneğin, yapılan bir programda kullanıcıya sunulan üç seçenekten birinin seçilmesi istendi (1, 2 ve 3 gibi). Ancak kullanıcı bunlar dışında bir seçeneği seçti (örnek 4 gibi). Bu durumda kullanıcı programda mantıksal bir hata oluşmasına sebep olmuştur. Dolayısıyla bu durumun kullanıcıya bildirilmesi gerekmektedir. Bunu yapabilmek için aşağıda söz dizimi görünen kodlama incelenmelidir.

Switch(seçenek) { Case 1: İşlemler; Case 2: İşlemler; Case 3: İşlemler; Default: throw ArgumantOutOfRangeException(“Yanlış seçenek”); }

Bu kodlamada görülen gibi kullanıcı 1, 2 ya da 3 ‘ün dışında bir seçenek seçildiğinde “Yanlış seçenek” mesajıyla uyarılacak bir özel durum oluşturulmuştur. Programcı olarak bundan sonra yapılacak şey ise bu hatayı catch ile yakalayıp kullanıcı uyarılmaktır.

Özel durum oluşturmak için kullanılan söz dizim aşağıdaki gibidir:

throw new exception();

Yukarıda söz dizeminde de görülen özel durum oluşturmak için throw ifadesi kullanılmalıdır. Bu ifade ile özel durum olarak belirlenen işlemler, kodlamada meydana gelen normal hatalar gibi catch ifadesi ile yakalanabilir.

Aşağıda programcıya has başka bir özel durum içeren bir örnek kodlama bulunacaktır. Bu örnek, klavyeden girilen iki sayı arasındaki işlem, yine klavyeden girilen işlem türüne (+, -, *, /) göre gerçekleştiren basit bir hesap makinesi örneğidir.

Örneğin, form görüntüsü aşağıdaki Resimde görüldüğü gibi olacaktır. Bu formda görüldüğü gibi “Birinci Sayı” ve “İkinci Sayı” kısımlarına girilecek iki sayı arasında, “Operatör” kısmına girilen karaktere göre (+, -, *, /) işlem yapan bir kodlama olacaktır. Ancak burada “Operatör” alanına bizim belirlenen karakter dışında da karakterler girilebilir. İşte bu durumun önüne geçmek için özel durum tanımlaması yapılacaktır.


Yukarıdaki resimdeki form görüntüsüne göre aşağıdaki gibi bir kodlama yapılabilir. Bu kodlamada da görülebileceği gibi şartlı dallanma yapısı için switch yapısı kullanılmıştır.


Resimde görülen kodlamada özel durum olarak InvalidOperationException (Geçersiz İşlem İstisnası) özel durumu kullanılarak hata tanımlaması yapılmıştır. Kullanıcı belirlediği karakterler (+, -, *, /) dışında bir karakteri “Operatör” alanına girdiğinde; “HATA! İşlem olarak +, -, *, / seçebilirsiniz.” hatası ile karşılaşacaktır. Çünkü oluşturulan özel durum aynı zamanda catch ifadesi ile yakalanmaktadır. Aşağıda böyle bir ekranla karşılaşma durum görülebilir.


Finally Bloku

Bir kodlamada bir özel durum oluşsa da oluşmasa da ifadenin her zaman çalıştığından emin olmanın yolu onu bir finally blokunun içine yazmaktır. Finally bloku, bir try blokundan hemen sonra ya da try blokundan sonraki son catch blokundan hemen sonra ortaya çıkar. Program finally blokuyla ilişkili try blokuna girdiği sürece finally bloku her zaman çalışacaktır.

finally blokunun söz dizimi aşağıdaki gibidir:

try {

Hata oluşmadığında çalışacak kodlamalar;

}

catch(hata yakalama)

{

Hata oluştuğunda çalışacak kodlamalar;

}

Finally

{

En son çalışacak kodlamalar;

}

Yukarıdaki söz diziminde de görüldüğü gibi program, try blokuna girdiğinde öncelikle burası çalışacaktır. Eğer buradaki kodların çalışması anında bir özel durum oluşursa catch blokunda bu özel durum yakalanacak ve catch blokundaki kodlar çalışacaktır. En sonunda da finally blokunda yer alan kodlar çalışacaktır. try blokundaki kodların çalışması anında herhangi bir hata oluşmazsa catch bloku atlanacak ve finally bloğu çalışacaktır. Kısacası finally bloku her durumda çalışacaktır. finally bloğu bu anlamda daha çok, oluşturulan nesnelerin bellekten temizlenmesi, açılan dosyaların kapatılması, veri tabanı bağlantısının ve nesnelerinin kapatılması, formda yer alan kontrollerdeki verilerin temizlenmesi gibi işlemler için kullanılan bir bölümdür.

Örnek: Aşağıdaki resimde yer alan form görüntüsüne göre klavyeden girilen iki sayıyı çarpıp sonucu “Sonuç” alanında görüntüleyen ve hesaplama işleminin sonunda her iki textbox kontrolündeki sayıyı temizleyen kodlama yapılmalıdır.


Örnekte kontrol temizleme işi olduğu için bu işi finally blokunda yapılmalıdır. Buna göre kodlama aşağıdaki şekilde yapılabilir:



Hakkında admin

Yorum Yap

Wordpress Tema indir