6. Hata yönetimi
KabaLang'de hata bildirmenin iki yolu vardır ve ikisi farklı iş içindir:
| Yol | Ne zaman | Yakalanmazsa |
|---|---|---|
sonuc<T, Hata> / belki<T> — dönüş değeri |
Olağan, beklenebilir başarısızlık (dosya yok, sayı ayrıştırılamadı) | Derleme hatası — yok sayamazsınız |
firlat / dene / yakala — istisna |
Programın devam edemeyeceği olağandışı durum | Program durur |
Kural: beklenen başarısızlık dönüş değeriyle, beklenmeyen durum istisnayla bildirilir.
sonuc<T, Hata> — başarı ya da hata
fonksiyon bol(a: sayi, b: sayi) -> sonuc<sayi, Hata>:
eger b == 0:
don hata("sıfıra bölme")
don tamam(a // b)
r = bol(10, 2)
dogrula(r.tamam_mi(), "başarılı olmalı")
dogrula(r.deger() == 5, "değer")
h = bol(1, 0)
dogrula(h.hatali_mi(), "hatalı olmalı")
yazdir("hata mesajı: " + h.hata().mesaj())
# Hata olursa yerine kullanılacak değer:
dogrula(bol(1, 0).deger_veya(-1) == -1, "deger_veya")
yazdir("sonuc tamam")| Yazım | Anlamı |
|---|---|
tamam(deger) |
başarı üret |
hata("mesaj") |
hata üret |
.tamam_mi() / .hatali_mi() |
hangisi olduğunu sor |
.deger() |
başarı değerini al |
.hata().mesaj() |
hata mesajını al |
.deger_veya(yedek) |
hata varsa yedek değeri ver |
? — hatayı yukarı yaymak
Her çağrıdan sonra eger hatali_mi() yazmak zorunda değilsiniz. ? işleci
"hata varsa bu fonksiyondan aynı hatayla dön" demektir:
fonksiyon bol(a: sayi, b: sayi) -> sonuc<sayi, Hata>:
eger b == 0:
don hata("sıfıra bölme")
don tamam(a // b)
fonksiyon iki_kati_bolum(a: sayi, b: sayi) -> sonuc<sayi, Hata>:
x = bol(a, b)? # hata varsa buradan hemen döner
don tamam(x * 2)
dogrula(iki_kati_bolum(10, 5).deger() == 4, "yayılma")
dogrula(iki_kati_bolum(10, 0).hatali_mi(), "hata yayıldı")
yazdir("? işleci tamam")⚠️ ? yalnız dönüş türü sonuc/belki olan bir fonksiyonun içinde
kullanılabilir. Dönüş türü olmayan bir fonksiyonda yazarsanız
KAPSAMSIZ_YAYILMA hatası alırsınız — hata sessizce kaybolmasın diye.
Sonucu yok saymak yasaktır
Bir sonuc döndüren çağrının sonucunu hiç kullanmazsanız derleme durur:
fonksiyon kaydet() -> sonuc<sayi, Hata>:
don tamam(1)
kaydet()
yazdir("buraya gelinmemeli")Ölçülen hata: [YOK_SAYILAN_SONUC] bu çağrı bir 'sonuc' döndürüyor ve sonuç
yok sayılıyor. Üç meşru çıkış yolu vardır:
fonksiyon kaydet() -> sonuc<sayi, Hata>:
don tamam(1)
# 1. Hatayı yay: x = kaydet()? (sonuc dönen bir fonksiyon içinde)
# 2. Karar ver:
r = kaydet()
eger r.hatali_mi():
yazdir("kaydedilemedi")
degilse:
yazdir("kaydedildi")
# 3. Bilerek yok say — niyet GÖRÜNÜR olur:
_ = kaydet()
yazdir("üç yol da geçerli")belki<T> — değer var ya da yok
Hata nedeni önemsizse (yalnız "var/yok" ayrımı gerekiyorsa) belki<T>
kullanılır:
fonksiyon ilk_eleman(l) -> belki<metin>:
eger l.uzunluk() == 0:
don bos
don dolu(l[0])
d = ilk_eleman(["a", "b"])
dogrula(d.var_mi(), "dolu")
dogrula(d.deger() == "a", "değer")
b = ilk_eleman([])
dogrula(b.bos_mu(), "boş")
dogrula(b.deger_veya("yok") == "yok", "deger_veya")
yazdir("belki tamam")⚠️ bos boş metin DEĞİLDİR. Bu ayrım konsol girdisinde can alıcıdır:
konsol.satir_oku() bir belki<metin> döner; bos "girdi bitti (Ctrl-D)",
dolu("") ise "kullanıcı yalnızca Enter'a bastı" demektir. Bu ayrım
olmasaydı okuma döngüsü ya sonsuza kadar döner ya da erken biterdi
(9. sayfa).
Açarak koşul — eger dolu x = …, iken dolu, koru … degilse
var_mi() + deger() çiftini (sırası unutulabilir) tek yazıma indirir.
Değer yalnız koşul tuttuğunda, yalnız o bloğun içinde kapsamdadır:
fonksiyon bul(l: liste<metin>, aranan: metin) -> belki<sayi>:
dongu i, x icinde l.numarali():
eger x == aranan:
don dolu(i)
don bos
fonksiyon bol(a: sayi, b: sayi) -> sonuc<sayi, Hata>:
eger b == 0:
don hata("sıfıra bölme")
don tamam(a // b)
eger dolu k = bul(["elma", "armut"], "armut"):
dogrula(k == 1, "dolu dalı")
degilse:
dogrula(yanlis, "buraya gelinmemeli")
eger tamam(q) = bol(17, 5):
dogrula(q == 3, "tamam dalı")
eger hata(h) = bol(1, 0):
dogrula(h.mesaj() == "sıfıra bölme", "hata dalı")iken dolu x = f(): her turda f()'i çağırır, bos gelince döngü biter
(iken dolu satir = konsol.satir_oku(): — Ctrl-D'ye kadar okur).
koru erken çıkış içindir: koşul tutmazsa gövde koşar ve gövde çıkmak
zorundadır (don, firlat, kir, devam ya da cikis(...); çıkmazsa
KORU_CIKMIYOR derleme hatası). koru dolu x = … degilse: ile açılan ad
koru'dan sonra kapsamdadır:
fonksiyon bul(l: liste<metin>, aranan: metin) -> belki<sayi>:
dongu i, x icinde l.numarali():
eger x == aranan:
don dolu(i)
don bos
fonksiyon ikiye(l: liste<metin>, m: metin) -> sonuc<sayi, Hata>:
koru dolu i = bul(l, m) degilse:
don hata(m + " bulunamadı")
don tamam(i * 2) # i burada sayi
dogrula(ikiye(["a", "b"], "b").deger_veya(-1) == 2, "koru dolu")
dogrula(ikiye(["a"], "z").hatali_mi(), "koru gövdesi çıktı")dolu, tamam, hata rezerve değildir: dolu x = (ad + =) dizilimi
dolu(x) çağrısından ayrıdır. Yanlış tür (eger dolu x = 5:) derleme
hatasıdır (ACARAK_TIP).
Birleştiriciler — donustur, sonra, veya_hata
fonksiyon bul(n: sayi) -> belki<sayi>:
eger n > 0:
don dolu(n)
don bos
fonksiyon yarim(x: sayi) -> belki<sayi>:
eger x % 2 == 0:
don dolu(x // 2)
don bos
dogrula(bul(5).donustur((x) => x * 2).deger_veya(0) == 10, "donustur: değer varsa işlev uygulanır")
dogrula(bul(-1).donustur((x) => x * 2).bos_mu(), "donustur: bos olduğu gibi geçer")
dogrula(bul(8).sonra(yarim).deger_veya(0) == 4, "sonra: işlev belki döndürür")
dogrula(bul(0).veya_hata("yok").hatali_mi(), "veya_hata: belki → sonuc")sonuc üzerinde de donustur(f) (başarı değerine uygular, hatayı aynen
geçirir) ve sonra(f) (f bir sonuc döndürür) vardır. İşlev bir işlev adı
ya da anonim işlev ((x) => …) olabilir.
dene / yakala / firlat — istisnalar
dene:
firlat "beklenmeyen durum"
yakala hata_mesaji:
yazdir(f"yakalandı: {hata_mesaji}")
# Hatayı adlandırmadan da yakalayabilirsiniz:
oldu = yanlis
dene:
firlat "isimsiz"
yakala:
oldu = dogru
dogrula(oldu, "anonim yakalama")
yazdir("istisna tamam")Hata yoksa yakala bloğu hiç çalışmaz:
sayac = 0
dene:
sayac = 1
yakala:
sayac = 2
dogrula(sayac == 1, "hata yokken yakala çalışmamalı")
yazdir("kontrol tamam")sonunda: — her durumda koşan temizlik
sonunda bloğu deneden nasıl çıkılırsa çıkılsın koşar: normal bitiş,
don, yakalanan hata ya da yukarı yayılan hata. Dosya kapatmak, geçici
dosyayı silmek, sayacı geri almak gibi işler içindir.
kayit = []
fonksiyon bol(a: sayi, b: sayi) -> sayi:
dene:
eger b == 0:
firlat "sıfıra bölme"
don a // b
yakala h:
kayit.ekle("hata: " + h)
don 0
sonunda:
kayit.ekle(f"bitti {a}/{b}")
dogrula(bol(8, 2) == 4, "normal yol")
dogrula(bol(1, 0) == 0, "hata yolu")
yazdir(kayit)yakala yazmadan da kullanılabilir; o zaman hata yakalanmaz, temizlik
koştuktan sonra yukarı yayılır.
⚠️ Kurallar (derleyici denetler):
sonundaiçindedon,kir,devamyazılamaz (SONUNDA_AKIS) — temizlik akışı değiştirirse dönüş değeri ya da hata sessizce kaybolurdu. Bloğun içindeki kendi döngüsündekir/devamserbesttir.deneiçinde tanımlanan bir adsonundada görünmez; temizlenecek şeyideneden önce tanımlayın.sonundabir anahtar sözcük değildir; yalnızdenebloğunun ardındansonunda:diye yazılınca bloktur, başka yerde değişken adı olabilir.
Hangi hata modeli nerede
- Kendi yazdığınız kütüphane fonksiyonları:
sonuc/belki— çağıran hatayı yok sayamaz, derleyici zorlar. - Programın ortasında "burası hiç olmamalıydı" durumu:
firlat. - ⚠️ Standart kütüphanenin birçok modülü (ağ, veritabanı, JSON) bugün hâlâ
hatayı sessizce bildirir — dönüş değeri boş/0 gelir. Bu modüllerin
dönüşünü elle denetleyin;
sonuca geçiş süren bir iştir (8. sayfa).
firlat hata("…") — hatayı nesne olarak fırlatmak
firlat iki yazımı da kabul eder ve ikisi aynı şeyi yapar:
fonksiyon yas_dogrula(yas: sayi):
eger yas < 0:
firlat hata("yaş negatif olamaz")
yazdir(f"yaş: {yas}")
dene:
yas_dogrula(31)
yas_dogrula(-1)
yakala h:
yazdir(f"yakalandı: {h}")
dogrula(dogru, "istisna yolu kapandı")
yazdir("program devam ediyor")firlat "yaş negatif olamaz" ile firlat hata("yaş negatif olamaz") aynı
metni fırlatır — hata modeli §4 kural 3nın
"geriye uyumluluk korunur" şartı budur ve ölçülür
(cekirdek/test_hata_firlat.py → IkiYazimAyniSonuc).
⚠️ GİDERİLEN KUSUR (2026-09-26): firlat hata("…") eskiden hiç
derlenmiyor, kullanıcı anlaşılmaz bir iç hata iletisi alıyordu. Bugün iki
yazım da derlenir ve aynı sonucu verir.
⚠️ yakala h: içindeki h bir metindir
h bugün Hata nesnesi DEĞİL, hatanın metnidir:
| Yazım | Bugün |
|---|---|
yazdir(h) · f"{h}" |
✅ çalışır |
metin(h) |
✅ çalışır |
h.mesaj · h.kod · h.konum |
❌ derlenmez |
⚠️ AÇIKÇA UYGULANMADI. Hata modeli §4
hnin bir Hata olmasını, yani makine okunur kodun KabaLang'dan
görünmesini ister. Bunun için firlat/yakala kod üretiminin değişmesi
gerekir (cekirdek/deyim_cozumu.py → _firlat / _yakala ·
cekirdek/derleyici.pynin aynı dalı) ve bu, sevk edilmiş yakala
kullanımlarını kıracak bir göçtür. Bugünkü alternatif: hata METNİYLE
çalışın; makine okunur dallanma gerekiyorsa sonuc<T, Hata> kullanın —
orada hata.kod okunabilir.
Hata iletilerinde sütun neden yazmıyor
Bir derleme hatası size dosya.kbl:12 der, dosya.kbl:12:34 demez:
✗ Hata #1: 'yok_boyle' adında bir değişken veya fonksiyon tanımlanmamış
▸ Konum: program.kbl:2
2 │ firlat yok_boyle("planli")
~~~~~~~~~~~~~~~~~~~~~~~~~~⚠️ GİDERİLEN KUSUR (2026-09-26): eskiden bir sütun BASILIYORDU ve
uydurmaydı — 25 karakterlik bir satır için :48 yazıyor, işaret satırın
çok ötesine düşüyordu. Sebebi, sütunun sizin .kbl dosyanızdaki konumdan
değil, derleme sırasında üretilen ara koddaki konumdan gelmesiydi; ikisinin
karakter karşılığı yoktur. Sütunu satır uzunluğuna kırpmak daha kötü olurdu:
makul ama yanlış bir sütuna kullanıcı inanır.
Gerçek sütun (hata modeli §3daki
Konum.sutun) AST konumlarına bağlı bir FAZ 5.5 borcudur; o gelene kadar
ileti satırın tamamını işaretler. Ölçüm: cekirdek/test_hata_firlat.py
→ SutunUydurmuyor · SapkaHizali.