Dart'ta Hata Yönetimi: Try-Catch ve Asenkron İşlemler

Hata Yönetimi ve Asenkron Programlama
Bugün iki önemli konuyu öğrendim: Hata yönetimi (Try-Catch) ve asenkron işlemler (Async-Await). İkisi de gerçek uygulamalarda çok kritik konular.
Canlı Demo: Try-Catch ve Async-Await
Hata yönetimi ve asenkron programlamayı interaktif olarak öğrenin:
Try-Catch - Hataları Yakalamak
Programlarımız her zaman kusursuz çalışmıyor. Kullanıcı yanlış bir şey girebilir, internet bağlantısı kopabilir, dosya bulunamayabilir. İşte Try-Catch tam da bu durumlar için.
İlk Karşılaştığım Problem
Kullanıcıdan sayı istiyorum ama kullanıcı harf giriyor. Program çöküyor:
import 'dart:io';
void main() {
print("Bir sayı girin:");
String girdi = stdin.readLineSync()!;
int sayi = int.parse(girdi); // Eğer harf girerse HATA!
print("Girdiğiniz sayı: $sayi");
}Kullanıcı "abc" yazarsa program patlar. Çözüm? Try-Catch!
Try-Catch ile Güvenli Hale Getirme
import 'dart:io';
void main() {
print("Bir sayı girin:");
try {
String girdi = stdin.readLineSync()!;
int sayi = int.parse(girdi);
print("Girdiğiniz sayı: $sayi");
} catch (e) {
print("Hata! Lütfen geçerli bir sayı girin.");
print("Hata detayı: $e");
}
}Şimdi kullanıcı ne yazarsa yazsın program çökmüyor. Hata olursa catch bloğu çalışıyor.
Sürekli Sayı İsteyen Program
Ben bunu bir adım ileri götürdüm. Kullanıcı doğru sayı girene kadar tekrar tekrar sor:
import 'dart:io';
void main() {
int sayi;
while (true) {
try {
print("Bir sayı girin:");
sayi = int.parse(stdin.readLineSync()!);
break; // Başarılıysa döngüden çık
} catch (e) {
print("Lütfen geçerli bir sayı giriniz!");
}
}
print("Tebrikler! Girdiğiniz sayı: $sayi");
}Bu kod kullanıcı doğru sayı girene kadar devam ediyor. Çok kullanışlı!
Finally Bloğu
Bazen hata olsa da olmasa da çalışmasını istediğiniz kod olabilir:
try {
// Riskli işlem
int sonuc = 10 ~/ 0; // Sıfıra bölme hatası
} catch (e) {
print("Hata oluştu: $e");
} finally {
print("Bu her zaman çalışır");
}finally bloğu ne olursa olsun çalışır. Genelde dosya kapatma, bağlantı kesme gibi işler için kullanılır.
Asenkron İşlemler - Async ve Await
Asenkron programlama konusu beni başta çok zorladı. Ama şöyle anladım: Bazı işlemler zaman alıyor (internet'ten veri çekme, dosya okuma vb.) ve bu işlemleri beklerken programın donmasını istemiyoruz.
Senkron vs Asenkron
Senkron (Normal):
İşlem 1 başla → İşlem 1 bitir → İşlem 2 başla → İşlem 2 bitirAsenkron:
İşlem 1 başla → İşlem 2 başla → İşlem 1 bitir → İşlem 2 bitirYani bir şey beklerken diğer şeyleri de yapabiliyorsunuz.
Future, Async, Await - Üçlü Kavram
Bu üç kelime hep birlikte kullanılıyor:
- Future: Gelecekte tamamlanacak bir işlem
- async: Fonksiyonun asenkron olduğunu belirtir
- await: İşlem bitene kadar bekle
İlk Async Örneğim
Future<void> main() async {
print("Veri bekleniyor...");
String veri = await veritabanindanVeriAl();
print("Veri alındı: $veri");
}
Future<String> veritabanindanVeriAl() async {
// 3 saniye bekle (veritabanını simüle ediyoruz)
await Future.delayed(Duration(seconds: 3));
return "Kullanıcı verileri";
}Bu kod şöyle çalışıyor:
- "Veri bekleniyor..." yazdır
veritabanindanVeriAl()fonksiyonunu çağır ve bekle (3 saniye)- Veri gelince "Veri alındı: ..." yazdır
Await Kullanmazsak Ne Olur?
Future<void> main() async {
print("Veri bekleniyor...");
String veri = veritabanindanVeriAl(); // HATA!
print("Veri alındı: $veri");
}Bu çalışmaz çünkü veritabanindanVeriAl() hemen değer döndürmüyor, bir Future döndürüyor. await kullanmadan Future'ı String'e çeviremezsiniz.
Daha Gerçekçi Bir Örnek
Future<void> main() async {
print("1. Veri bekleniyor...");
var veri = await veritabanindanVeriAl();
print("2. Veri alınıyor: $veri");
}
Future<String> veritabanindanVeriAl() async {
// Her saniye yükleme durumunu göster
for (var i = 1; i <= 5; i++) {
await Future.delayed(
Duration(seconds: 1),
() => print("Yükleniyor... %${i * 20}")
);
}
return "Veritabanı kümesi";
}Çıktı:
1. Veri bekleniyor...
Yükleniyor... %20
Yükleniyor... %40
Yükleniyor... %60
Yükleniyor... %80
Yükleniyor... %100
2. Veri alınıyor: Veritabanı kümesiTry-Catch ile Async Kullanımı
Asenkron işlemlerde de hata olabilir (internet kesildi, timeout vb.):
Future<void> main() async {
try {
print("API'den veri çekiliyor...");
String veri = await apidenVeriCek();
print("Veri: $veri");
} catch (e) {
print("Hata oluştu: $e");
print("İnternet bağlantınızı kontrol edin");
}
}
Future<String> apidenVeriCek() async {
await Future.delayed(Duration(seconds: 2));
// Hata simülasyonu
throw Exception("Sunucuya bağlanılamadı!");
// return "API Verisi"; // Normalde bu çalışırdı
}Flutter'da Kullanım
Flutter'da sürekli async kullanıyoruz. Çünkü:
- API'lerden veri çekiyoruz
- Veritabanı işlemleri yapıyoruz
- Dosya okuyoruz
- Kullanıcı girişi bekliyoruz
Flutter'da API Çağrısı Örneği
class VeriSayfasi extends StatefulWidget {
@override
_VeriSayfasiState createState() => _VeriSayfasiState();
}
class _VeriSayfasiState extends State<VeriSayfasi> {
String veri = "Yükleniyor...";
@override
void initState() {
super.initState();
verileriYukle();
}
Future<void> verileriYukle() async {
try {
// API çağrısı yap (örnek)
await Future.delayed(Duration(seconds: 2));
setState(() {
veri = "Veriler başarıyla yüklendi!";
});
} catch (e) {
setState(() {
veri = "Hata: $e";
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text(veri),
),
);
}
}FutureBuilder Widget'ı
Flutter'da Future'ları göstermek için özel bir widget var:
FutureBuilder<String>(
future: veritabanindanVeriAl(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator(); // Loading göster
}
if (snapshot.hasError) {
return Text("Hata: ${snapshot.error}"); // Hata göster
}
return Text("Veri: ${snapshot.data}"); // Veri göster
},
)Bu widget otomatik olarak loading, hata ve başarı durumlarını yönetiyor. Çok kullanışlı!
Async-Await Kullanırken Dikkat Edilecekler
Öğrendiğim bazı önemli kurallar:
- await sadece async fonksiyonlarda kullanılır
// YANLIŞ
void fonksiyon() {
await birSey(); // HATA!
}
// DOĞRU
Future<void> fonksiyon() async {
await birSey(); // Tamam
}- async fonksiyon mutlaka Future döndürür
Future<String> veriAl() async {
return "Veri";
}- Birden fazla await kullanabilirsiniz
Future<void> tumVerileriAl() async {
String veri1 = await api1denVeriAl();
String veri2 = await api2denVeriAl();
String veri3 = await api3denVeriAl();
print("$veri1, $veri2, $veri3");
}- Paralel çalıştırmak için Future.wait
Future<void> parallelVeriler() async {
// Üçü aynı anda başlar
var sonuclar = await Future.wait([
api1denVeriAl(),
api2denVeriAl(),
api3denVeriAl(),
]);
print(sonuclar); // [veri1, veri2, veri3]
}Bugün Ne Öğrendim?
- Try-Catch ile hataları güvenli şekilde yakalıyoruz
- Finally bloğu her durumda çalışır
- Async-Await ile asenkron işlemleri yönetiyoruz
- Future gelecekte tamamlanacak işlemler için
- Flutter'da FutureBuilder çok işe yarıyor
Yarın Flutter'ın UI yapısına (Widget ağacı, Row, Column, Stack) bakacağım. Artık kod tarafını iyi öğrendim, şimdi arayüz zamanı!
Sorularınız mı var?
Kodlamaya devam! 🚀
İlgili Yazılar
Flutter: FutureBuilder ile Asenkron Listeleme
Flutter'da FutureBuilder kullanımı, async/await ile widget entegrasyonu, ListView ve GridView ile asenkron veri listeleme.
Flutter'da Kamerayı Kullanıcıya Bırakmak: Yön Zorlamadan Video Çekmek
Flutter camera paketinde önizlemenin ters dönmesi, kayıt başlarken donma ve bildirim merkezi açılınca kameranın kilitlenmesi. Recapday'i geliştirirken çözdüğüm üç somut hatayı ve yön zorlamadan çalışan kamera ekranının kodunu anlatıyorum.
ffmpeg ile Telefonda Video Birleştirme: Farklı Oranlardaki Klipleri Tek Vloga Çevirmek
Kimi dikey kimi yatay, kimi video kimi fotoğraf. Recapday'de bu karışımı sunucu kullanmadan, telefonda tek bir 1920x1080 vloga çeviren ffmpeg zincirini adım adım anlatıyorum: bulanık dolgu, Türkçe karakterli yazı, müzik ve ölçülmüş sıkıştırma.