---
title: 'Hata Yönetimi'
source: 'https://academia.sh/tr/kurslar/javascript-temelleri/hata-yonetimi'
course: 'JavaScript Temelleri'
language: tr
updated: '2026-08-17T18:09:46+00:00'
license: 'CC BY-SA 4.0'
---

# Hata Yönetimi

`try`/`catch`/`finally` akışı, `throw` deyimi, yerleşik hata tipleri, hata nesnesinin alanları, neden zinciri ve hata ile dönüş değeri arasındaki seçim.

Önceki derslerde `try`/`catch` yapısı hata iletilerini göstermek için kullanıldı ama
tanımlanmadı. Bu ders yapıyı tamamlar: blokların akışı, hata fırlatma, yerleşik hata
tipleri ve — en önemlisi — bir sorunun hata mı yoksa dönüş değeri mi olarak
bildirileceği kararı.

Kod Çalıştırma Yolları dersinde hata nesnesinin ad, ileti ve yığıt izi taşıdığı
gösterilmişti. Burada bu nesneleri kendimiz üreteceğiz.

## Blokların Akışı

`try` bloğu izlenen kodu içerir. Hata oluşursa akış `catch` bloğuna atlar. `finally`
bloğu, hata olsun olmasın çalışır.

```js
function dene(deger) {
  try {
    console.log("1 try basi");
    if (deger < 0) throw new Error("negatif deger");
    console.log("2 try sonu");
    return "try donusu";
  } catch (hata) {
    console.log("3 catch:", hata.message);
    return "catch donusu";
  } finally {
    console.log("4 finally");
  }
}
console.log(dene(1));
console.log("---");
console.log(dene(-1));
```

```
1 try basi
2 try sonu
4 finally
try donusu
---
1 try basi
3 catch: negatif deger
4 finally
catch donusu
```

İki gözlem önemlidir. Birincisi, hata oluştuğunda `try` bloğunun kalan satırları
çalışmaz; akış doğrudan `catch`'e geçer. İkincisi, `finally` bloğu `return` deyiminden
**sonra** ama fonksiyon gerçekten dönmeden **önce** çalışır. Bu yüzden temizlik işleri
oraya yazılır: açılan bir kaynağın kapatılması, ayrılan bir kilidin bırakılması.

`finally` içinde `return` yazmak, dönüş değerini ezer:

```js
function ezer() {
  try {
    return "try";
  } finally {
    return "finally";
  }
}
console.log(ezer());
```

```
finally
```

Aynı davranış fırlatılan hatayı da yutar. Bu yüzden `finally` bloğu yalnızca temizlik
içerir; akışı yönlendiren bir deyim taşımaz.

Hata nesnesine ihtiyaç yoksa yakalama bağı yazılmayabilir:

```js
function gecerliJson(metin) {
  try {
    JSON.parse(metin);
    return true;
  } catch {
    return false;
  }
}
console.log(gecerliJson('{"a":1}'), gecerliJson("{bozuk}"));
```

```
true false
```

## Yerleşik Hata Tipleri

Standart birkaç hata tipi tanımlar ve dilin kendi ürettiği hatalar bunlardan biridir:

```js
const denemeler = [
  () => null.x,
  () => bilinmeyenAd,
  () => ([].length = -1),
  () => (1234).toFixed(200),
];
for (const d of denemeler) {
  try {
    d();
  } catch (hata) {
    console.log(hata.name + ": " + hata.message);
  }
}
```

```
TypeError: Cannot read properties of null (reading 'x')
ReferenceError: bilinmeyenAd is not defined
RangeError: Invalid array length
RangeError: toFixed() digits argument must be between 0 and 100
```

`TypeError` bir değerin beklenen türde olmadığını, `ReferenceError` bir adın
bulunamadığını, `RangeError` bir değerin izin verilen aralığın dışında olduğunu bildirir.
`SyntaxError` ise ayrıştırma sırasında üretilir; ilk derste görüldüğü gibi programı hiç
başlatmaz — tek istisnası, metin ayrıştıran yerleşik yöntemlerin çalışma zamanında
ürettiği durumdur.

Hata **adları** standarttır; **iletiler** değildir. İleti metinleri çalışma zamanları
arasında ve sürümler arasında değişir. Bu yüzden kodda ileti metnine göre dallanılmaz;
ada, tipe veya kendi eklediğimiz bir alana bakılır.

## Hata Fırlatmak

`throw` deyimi herhangi bir değeri fırlatabilir. Fırlatılan şeyin hata nesnesi olması
zorunlu değildir, ama olmalıdır:

```js
try {
  throw "duz metin";
} catch (hata) {
  console.log(typeof hata, hata);
  console.log("name:", hata.name, "| stack:", typeof hata.stack);
}

try {
  throw new Error("hata nesnesi");
} catch (hata) {
  console.log(typeof hata, hata instanceof Error);
  console.log("name:", hata.name, "| stack:", typeof hata.stack);
}
```

```
string duz metin
name: undefined | stack: undefined
object true
name: Error | stack: string
```

Metin fırlatıldığında ad ve yığıt izi yoktur; hatanın nereden geldiği kaybolur. Kursun
kuralı: **fırlatılan her değer bir hata nesnesidir.**

Alt katmandaki bir hatayı sararken özgün hata korunmalıdır. Hata nesnesi bunun için bir
**neden (cause)** alanı taşıyabilir:

```js
function sicaklikCevir(metin) {
  const deger = Number(metin);
  if (Number.isNaN(deger)) {
    throw new Error(`sayiya cevrilemedi: ${JSON.stringify(metin)}`);
  }
  return deger;
}

function kaydiOku(satir) {
  const [istasyon, sicaklikMetni] = satir.split(";");
  try {
    return { istasyon, sicaklik: sicaklikCevir(sicaklikMetni) };
  } catch (hata) {
    throw new Error(`kayit okunamadi: ${istasyon}`, { cause: hata });
  }
}

console.log(kaydiOku("A1;21.5"));
try {
  kaydiOku("B2;abc");
} catch (hata) {
  console.log(hata.message);
  console.log("neden:", hata.cause.message);
}
```

```
{ istasyon: 'A1', sicaklik: 21.5 }
kayit okunamadi: B2
neden: sayiya cevrilemedi: "abc"
```

Üst katman kendi bağlamını ekledi (hangi kayıt), alt katmanın bilgisi (neden) kayboldu
sayılmadı. Bu, hata iletilerini bağlamla zenginleştirmenin standart yoludur.

## Kendi Hata Tipini İşaretlemek

Bir hatayı kendi ürettiğimizi ayırt edebilmek gerekir; aksi halde `catch` bloğu, kodun
kendi hatalarıyla birlikte beklenmedik programlama hatalarını da yutar.

En yalın yol, hata nesnesine ad ve bir kod alanı eklemektir:

```js
function olcumHatasi(kod, ileti) {
  const hata = new Error(ileti);
  hata.name = "OlcumHatasi";
  hata.kod = kod;
  return hata;
}

const h = olcumHatasi("BOS_ALAN", "sicaklik alani bos");
console.log(h.name, "|", h.kod, "|", h.message, "|", h instanceof Error);
```

```
OlcumHatasi | BOS_ALAN | sicaklik alani bos | true
```

Kalıtımla adlandırılmış hata sınıfları tanımlamak — sınıf sözdizimi kullanarak — bir
sonraki kursun konusudur. Bu kursta ad ve kod alanı yeterlidir.

## Ölçüm Betiğine Uygulama

Bozuk veriye verilen yanıt artık bir sözleşmeye bağlanabilir: her satır ya kabul edilir
ya da gerekçesiyle reddedilir; hiçbir satır sessizce yanlış değere dönüşmez.

```js
const KOD_BOS = "BOS_ALAN";
const KOD_SAYI = "SAYI_DEGIL";

function olcumHatasi(kod, ileti) {
  const hata = new Error(ileti);
  hata.name = "OlcumHatasi";
  hata.kod = kod;
  return hata;
}

function sicaklikOku(metin) {
  if (metin.trim() === "") {
    throw olcumHatasi(KOD_BOS, "sicaklik alani bos");
  }
  const deger = Number(metin);
  if (Number.isNaN(deger)) {
    throw olcumHatasi(KOD_SAYI, `sicaklik sayiya cevrilemedi: ${JSON.stringify(metin)}`);
  }
  return deger;
}

const satirlar = ["A1;21.5", "A2;", "B1;abc", "B2;0"];
const kabul = [];
const red = [];

for (const satir of satirlar) {
  const [istasyon, alan] = satir.split(";");
  try {
    kabul.push({ istasyon, sicaklik: sicaklikOku(alan) });
  } catch (hata) {
    if (hata.name !== "OlcumHatasi") throw hata;
    red.push({ istasyon, kod: hata.kod, ileti: hata.message });
  }
}

console.log("kabul:", kabul);
console.log("red:", red);
```

```
kabul: [ { istasyon: 'A1', sicaklik: 21.5 }, { istasyon: 'B2', sicaklik: 0 } ]
red: [
  { istasyon: 'A2', kod: 'BOS_ALAN', ileti: 'sicaklik alani bos' },
  {
    istasyon: 'B1',
    kod: 'SAYI_DEGIL',
    ileti: 'sicaklik sayiya cevrilemedi: "abc"'
  }
]
```

Üç karar bu betiği önceki sürümlerinden ayırıyor.

Birincisi, `B2` kaydındaki `0` değeri kabul edildi. Doğruluk Değerleri dersinde kurulan
ayrım korunuyor: sıfır geçerli bir ölçümdür.

İkincisi, yakalama bloğu **kendi hatasını tanıyor**. `hata.name !== "OlcumHatasi"`
denetimi, beklenmedik bir hatayı yeniden fırlatıyor. Bu satır olmasaydı, örneğin
`satir.split` çağrısında oluşacak bir `TypeError` de "reddedilen kayıt" sayılır ve
programlama hatası veri hatası gibi görünürdü.

Üçüncüsü, red listesi gerekçe taşıyor. Kaç kaydın neden reddedildiği çıktıdan
okunabiliyor.

## Hata mı, Dönüş Değeri mi

Her olağandışı durum hata değildir. Ölçüt şudur: **çağıran taraf durumu öngörebiliyorsa
dönüş değeri, öngöremiyorsa hata uygundur.**

Boş bir listenin ortalamasını istemek öngörülebilir bir durumdur; Fonksiyon Bildirimi ve
İfadesi dersindeki `ortalama` fonksiyonu bu yüzden `null` döndürdü. Buna karşılık,
sayısal olması gereken bir alanda harf bulunması verinin sözleşmesinin ihlalidir; hata
uygundur.

İki uygulama da yukarıdaki betikte bir arada bulunuyor: `sicaklikOku` hata fırlatıyor,
çağıran döngü hatayı yakalayıp bir veri yapısına — red listesine — çeviriyor. Sınır,
sorunun nerede ele alınabileceğine göre çizilir.

Hatalar akış denetimi için kullanılmaz. Bir döngüden çıkmak, bir değeri atlamak veya bir
koşulu bildirmek için hata fırlatmak, hem maliyetli hem de okunması güç bir kalıptır;
`break`, `continue` ve dönüş değerleri bu iş içindir.

## Özet

- `try` bloğunda hata oluşursa kalan satırlar çalışmaz; `finally` her durumda ve `return`
  değerlendirildikten sonra çalışır.
- `finally` içinde `return` veya `throw` yazmak, dönüş değerini ve hatayı ezer; blok
  yalnızca temizlik içerir.
- Hata adları standarttır, iletiler değildir; dallanma ileti metnine göre yapılmaz.
- Fırlatılan her değer hata nesnesi olmalıdır; aksi halde ad ve yığıt izi bulunmaz.
- Sarmalanan hatalar `cause` alanıyla korunur; kendi hataları ad ve kod alanıyla
  işaretlenir ve tanınmayan hatalar yeniden fırlatılır.
- Öngörülebilir durum dönüş değeriyle, sözleşme ihlali hatayla bildirilir.

## Sonraki Adım

Denetim akışı ve fonksiyonlar tamamlandı. Bu konudaki örneklerde `filter`, `map`, `split`
ve nesne yayma gibi yapılar açıklanmadan kullanıldı. Sonraki konu bunları tanımlayacak:
dizilerin oluşturma ve dönüştürme yöntemleri, nesne erişim kısayolları, şablon dizgileri,
JSON dönüşümleri ve tarih–zaman gösterimi. Ölçüm listesi orada metinden okunup metne geri
yazılan tam bir veri kümesine dönüşecek.
