Menu

JavaScript Hata Türleri: SyntaxError, TypeError

JavaScript'in yerleşik hata türleri: her biri ne anlama geliyor, ne zaman karşına çıkar ve hata mesajını tahmin yürütmeden nasıl okursun.

Hatalar, Bir Türü Olan Nesnelerdir

JavaScript bir hata fırlattığında size sadece düz bir metin vermez; aslında bir nesne verir. Bu nesnenin bir türü (yani constructor'ı) ve birkaç standart özelliği vardır: name, message ve stack.

index.js
Output
Click Run to see the output here.

err.name, "TypeError" gibi kısa bir etikettir. err.message ise insanın okuyabileceği açıklamadır. err instanceof TypeError ile de hatanın hangi sınıfa ait olduğunu öğrenirsin. Hatanın türünü bilmek önemli: sorunun bir yazım hatası mı, geçersiz bir değer mi, yoksa hiç parse bile edilememiş bir kod mu olduğunu sana söyler.

JavaScript'te yedi adet yerleşik hata türü vardır. Üçüyle sürekli karşılaşırsın, dördüyle ise arada sırada.

SyntaxError: Kod Parse Edilemedi

SyntaxError, JavaScript'in kodunu okuyamadığı anlamına gelir. Aslında bu tam olarak bir çalışma zamanı hatası değildir — motor, tek bir satır bile çalışmadan, parse aşamasında patlar. Bu yüzden aynı dosya içinde SyntaxErrortry/catch ile yakalayamazsın; çünkü dosyanın tamamı baştan reddedilir.

function greet(name {
    return "hi, " + name;
}
// SyntaxError: Unexpected token '{'

Eksik parantez, kaçak bir virgül ya da fonksiyon dışında kalmış bir return — dilin gramerini bozan her şey bu hatayı fırlatır. Çözüm her zaman aynı: kaynak kodu düzeltmek. SyntaxError'ı gerçekten yakalayabileceğin tek yer ise çalışma zamanında ayrıştırma yapılan durumlar, örneğin JSON.parse:

index.js
Output
Click Run to see the output here.

JSON.parse çalışma zamanında bir string aldığı için ondan gelen sözdizimi hatalarını try/catch ile yakalayabilirsin. Ama kendi kaynak dosyalarındaki SyntaxError'ları yakalayamazsın.

ReferenceError: Böyle Bir Değişken Yok

ReferenceError, mevcut kodun görebildiği hiçbir kapsamda (scope) tanımlanmamış bir değişkene erişmeye çalıştığında fırlatılır.

index.js
Output
Click Run to see the output here.

Onda dokuz, bunun sebebi basit bir yazım hatasıdır (total yerine totl yazmak gibi). Kalan yüzde onluk kısımda ise olay kapsamla (scope) ilgilidir — farklı bir fonksiyonda ya da modülde tanımladığın bir şeyi kullanmaya çalışıyorsundur.

Bir de daha sinsi bir sebep var: temporal dead zone (geçici ölü bölge). let ve const ile yapılan tanımlamalar, bulundukları bloğun en tepesinden itibaren var olur; ama tanımlandıkları satıra gelinmeden onlara erişemezsin:

index.js
Output
Click Run to see the output here.

console.log(x) çalıştığı anda x aslında gerçek bir binding olmuş durumda; ama henüz initialize edilmemiş. İşte reference error'un sebebi bu. Çözüm de basit: erişimi declaration'ın altına taşımak.

TypeError: Değerin Tipi Beklenenle Uyuşmuyor

JavaScript'te TypeError, değerin var olduğunu ama yapılmak istenen işleme uygun türde olmadığını gösterir. Function olmayan bir şeyi çağırmak, null ya da undefined üzerinden property okumak, bir const'a yeniden atama yapmak — hepsi birer TypeError.

index.js
Output
Click Run to see the output here.

Cannot read properties of null (reading 'name') ifadesindeki "Cannot read properties of null" hatası, JavaScript'te karşılaşacağınız muhtemelen en yaygın hata mesajıdır. Çözüm ya değerin mevcut olduğundan emin olmak ya da erişimi optional chaining ile korumaktır: user?.name.

TypeError'ın diğer çeşitleri:

index.js
Output
Click Run to see the output here.

Bir sayıyı fonksiyon gibi çağırmak, const bir değişkene yeniden atama yapmak ya da var olmayan bir metodu çağırmak — kısacası değerin türü, ondan yapmasını istediğin şeye uygun değil.

RangeError: Sayı İzin Verilen Aralığın Dışında

RangeError, bir sayı teknik olarak geçerli olsa da belirli bir işlem için izin verilen aralığın dışına çıktığında fırlatılır.

index.js
Output
Click Run to see the output here.

Klasik örneği sonsuz rekürsiyondur; çağrı yığınını (call stack) taşırır:

index.js
Output
Click Run to see the output here.

"Maximum call stack size exceeded" hatası neredeyse her zaman ya bir fonksiyonun kendisini base case olmadan çağırmasından ya da iki fonksiyonun birbirini sonsuz döngüde çağırmasından kaynaklanır.

URIError ve EvalError: Nadir Görülenler

URIError, URI ile ilgili fonksiyonlara (encodeURI, decodeURIComponent ve benzerleri) bozuk bir girdi verdiğinizde karşınıza çıkar:

index.js
Output
Click Run to see the output here.

EvalError artık tarihe karışmış bir hata türü. Modern JavaScript motorları bu hatayı aslında hiçbir durumda fırlatmıyor; geriye dönük uyumluluk adına sadece bir constructor olarak duruyor. Elle oluşturabilirsiniz, ama gerçek hayatta karşınıza çıkmaz.

Hata sınıflarının kalıtım zinciri

Saydığımız tüm hata türleri temel Error sınıfından türüyor. Yani hangisi olursa olsun err instanceof Error ifadesi true döner. Bu da genel bir catch bloğunda işinizi bir hayli kolaylaştırır:

index.js
Output
Click Run to see the output here.

catch bloğu her şeyi yakalar — biri throw "oops" yazdıysa onu bile. İşte bu yüzden son daldaki kontrol önemli. Yakaladığınız değeri error nesnesi gibi kullanmadan önce mutlaka instanceof ile türünü daraltın.

Bilinçli olarak hata fırlatmak

Kodunuz bir sorun tespit ettiğinde, yerleşik hata türlerinden herhangi birini kendiniz de fırlatabilirsiniz. Sadece yaşanan soruna en uygun türü seçin:

index.js
Output
Click Run to see the output here.

Hata tipini başarısızlığa göre doğru seçmek sadece kozmetik bir detay değil; çağıran tarafın hata mesajlarını string olarak parse etmek zorunda kalmadan, hedefe yönelik catch blokları yazabilmesini sağlıyor.

Özel Error Sınıfları (Custom Error Class)

Yerleşik hata tipleri ihtiyacınızı karşılamıyorsa Error sınıfını extend edin:

index.js
Output
Click Run to see the output here.

İki nokta aklınızda olsun: super(message) çağrısını yapın ki temel Error sınıfı düzgün kurulabilsin ve this.name değerini atayın ki loglarda doğru etiket görünsün. field gibi özel alanlar da çağıran tarafın, string içinde arama yapmak zorunda kalmadan belirli hata durumlarına tepki vermesini sağlar.

Sırada: Console ve DevTools

Hata türlerini bilmek işin yarısı — diğer yarısı ise stack trace okumak ve program çalışırken state'e bakabilmek. Tarayıcının devtools'u (ve Node'un debugger'ı), "bir hata fırlattı ama nedenini bilmiyorum" durumunu birkaç saniyelik bir incelemeye çeviriyor. Sıradaki konumuz bu.

Sıkça Sorulan Sorular

JavaScript'te yerleşik hata türleri hangileri?

JavaScript'te toplam yedi tane var: temel sınıf olan Error, ardından SyntaxError, ReferenceError, TypeError, RangeError, URIError ve EvalError. Her biri; name, message ve stack özelliklerine sahip bir hata nesnesi üreten bir constructor. Uygulamada en sık karşılaşacakların SyntaxError, ReferenceError ve TypeError olacak.

SyntaxError ile TypeError arasındaki fark ne?

SyntaxError, kodun geçerli JavaScript olmadığı anlamına gelir — motor kodu ayrıştıramıyor (parse edemiyor) bile. TypeError ise kod sorunsuz parse edilmiş ama çalışma zamanında geçersiz bir iş yapılmış demektir: fonksiyon olmayan bir şeyi çağırmak ya da null üzerinden bir property okumak gibi. Syntax hataları tüm script'i baştan durdurur; type hataları ise yalnızca sorunlu satır çalıştığında fırlatılır.

JavaScript'te ReferenceError ne zaman alırım?

Tanımlanmamış bir isim kullandığında veya bir let/const değişkenine temporal dead zone içinde (tanımdan önce) eriştiğinde. En yaygın sebebi yazım hataları: consoel.log(x) yazdığında ReferenceError: consoel is not defined fırlar. Önce yazımı ve scope'u kontrol et.

Kendi hata türlerimi oluşturabilir miyim?

Tabii ki. Yerleşik Error sınıfını extend etmen yeterli: class ValidationError extends Error { }. Constructor içinde this.name değerini ayarlamayı unutma; böylece loglarda ve catch bloklarında hatayı ayırt edebilirsin. Farklı hata durumları farklı şekilde ele alınacaksa custom error sınıfları kendini fazlasıyla ödetir.

Coddy ile kodlamayı öğren

BAŞLA