Yazımızın içeriğine aşağıdan video olarak bakabilirsiniz.
try – catch – finally – throw
Nedir try, catch? Öncelikle buna bir bakalım. Arkadaşlar ingilizce olan try kelimesi dene anlamına gelir. Catch ise yakala anlamına gelir. Buradan şu anlaşılabilir ki hata olabilecek bir kodu try ile deneyeceğiz ve catch ile de yakalayacağız.
Şimdiye kadar yazdığımız kodları ders amaçlı bilinçli bir şekilde yazdık ve kodlarımız güzelce çalıştı. Ancak işler gerçek uygulamalarda runtime, çalışma anında böyle düzgün gitmez. Hata denetimi yapmak mecburiyetinde kalırız.
Örneğin derslerimizde biz kullanıcıdan bir sayı istedik ve sonra kullanıcı bu veriyi vermiş gibi yazdık. Ya kullanıcı gerçek hayatta sayı yerine bize adını yazarsa işte o zaman işler karışır ve programımız hata verir yazılımımız çökebilir.
Peki madem kodlarımız hata verebilir biz bütün kodlarımıza hata denetimi mi yapacağız. Tabi ki hayır, bu mümkün olmaz. Aşağıdaki örneklerimizi inceleyelim.
/* örneğin aşağıdaki yazacağımız bir kod için bir hata denetimi yapmak gereksiz olacaktır.
Basit bir kod ve zaten herşey belli. */
print ("Merhaba Dünya ");
Diyelim ki biz bir kullanıcıdan int tipinde bir veri istiyoruz ve o bize adını yazıyor. İşte bu gibi durumlarda hata denetimi yapmak yerinde olacaktır. Aşağıdaki kodumuzu inceleyim.
import 'dart:io';
//kullanıcıdan veri almak için importumuzu yaptık
void main(List<String> args) {
try {
//hata olma olasılığı yüksek kodumuzu try bloğu içerisine yazdık.
print("lütfen bir sayı giriniz");
int sayi = int.parse(stdin.readLineSync()!);
//kullanıcıdan int tipinde vermesini istediğimiz bir değer girmesini istedik.
//kullanıcı bize sayı yerine ismini girerse aşağıdaki resimdeki gibi bir çıktı verecektir
print(sayi);
}
catch (e) {
//catch bloğu ile hatamızı yakaladık ve print ile yazdırdık.
print("hata meydana geldi " + e.toString());
//hatamızı yakaladık
//ÇIKTI: hata meydana geldi FormatException: Invalid radix-10 number (at character 1)
}
print("devam eden kod");
}
finally ise catch bloğundan sonra açtığımız bir kod bloğu. Bu sayede hata olsa da olmasa da finally içerisindeki kodlarımız çalışır. Özel durumlar harici pek kullanılmaz.
void main(List<String> args) {
try {
int sayi = 10 ~/ 3;
//10 / 3 yazsaydık hata çıkacaktı. Tilde işareti
//ile ondalıklı kısmını attı ve bir int miş gibi
//davrandı. Bu yüzden hata almadık. Sonucuna bakalım.
print(sayi);
} catch (e) {
print("hata meydana geldi " + e.toString());
} finally {
print("her halükarda çalışır, hata çıksada, çıkmasada");
}
print("devam eden kod");
}
/* SONUÇ HATA VERMEDİ AMA KOD HATA VERMEYE ÇOK MÜSAİT AŞAĞIDAKİ ÖRNEKLERİ İNCELEYELİM
3
her halükarda çalışır, hata çıksada, çıkmasada
devam eden kod
*/
Peki yukarıdaki örneğin aynısını aşağıda 10 ~/ 0 şeklinde yapalım. Bu sefer bize onun sıfıra bölümünün tanımsız olmasından dolayı hata verecektir.
Aşağıdaki kodumuzda böleni bir String olarak gönderelim ve format hatası alalım.
//FORMAT HATASI VERDİRİYORUZ, BİR ALTTAKİ RESMİ İNCELEYİN.
void main(List<String> args) {
try {
int sayi = 10 ~/ int.parse("eser");
//10 ~/ eser ile yazdığımızda hata yokmuş gibi gözüküyor
//Hata verecek, sonuçlarını bir inceleyelim
print(sayi);
} catch (e) {
print("hata meydana geldi " + e.toString());
} finally {
print("her halükarda çalışır, hata çıksada, çıkmasada");
}
print("devam eden kod");
}
/* SONUÇ
hata meydana geldi FormatException: Invalid radix-10 number (at character 1)
eser
^
//Artık Hatamızın FormatException olduğunu biliyoruz.
//Çıkabilecek hatalara özel durumlar oluşturabiliriz.
her halükarda çalışır, hata çıksada, çıkmasada
devam eden kod
*/
Aşağıda çıkabilecek hatalara karşı özel hata durumları oluşturduk.
void main(List<String> args) {
try {
int sayi = 10 ~/ int.parse("eser");
//10 ~/ eser ile yazdığımızda hata yokmuş gibi gözüküyor
//Hata verecek, sonuçlarını bir inceleyelim
print(sayi);
} on FormatException catch (e) {
print("Format Hatası meydana geldi");
} on IntegerDivisionByZeroException catch (e) {
print("Sıfıra Bölme Hatası Çıktı");
} catch (e) {
print("Beklenmedik Hata" + e.toString());
} finally {
print("her halükarda çalışır, hata çıksada, çıkmasada");
}
}
Dart Hata fırlatma – throw
Kodlarımızda hata çıkabilecek alanlara kendimize özgü hatalar fırlatalım. Aşağıdaki örnekte kullanıcıdan pozitif bir tam sayı girmesini istiyoruz. Ancak kullanıcının bize negatif ve String tipinde veri gönderme ihtimaline karşı if ile sorgulamalar yapıyoruz ve hataya özgü hata fırlatıyoruz. en aşağıda da catch ile yakalıyoruz.
import 'dart:io';
void main(List<String> args) {
try {
print("Lütfen pozitif bir tamsayı giriniz");
String sayi = stdin.readLineSync()!.trim();
//kullanıcıdan pozitif veri girmesini istiyoruz.
//kullanıcı bize sayı yerine adını yazabilir.
//kullanıcı bize negatif değer gönderebilir
//kullanıcı boş bırakabilir
if (sayi.isEmpty) {
throw FormatException("Boş bırakılamaz");
} else if (sayi.contains(RegExp(r'[\d]')) == false) {
throw FormatException("Lütfen sayı giriniz");
} else if (int.parse(sayi).isNegative) {
throw FormatException("sayı negatif olamaz");
}
print("girilen sayının karesi ${int.parse(sayi) * int.parse(sayi)}");
//girilen sayının karesini alıp ekrana yazdırıyoruz
} catch (e) {
print(e.toString());
}
}
//SONUÇ
//Boş girersek: FormatException: Boş bırakıldı
//Negatif sayı girersek: FormatException: sayı negatif olamaz
//String bir değer yazarsa: FormatException: Lütfen sayı giriniz