Tartışma

Custom Error Sınıfları Oluşturma

Başlatan APIHunter · 15 Tem 2026 16:11 · 14 Görüntülenme · 0 Yanıtlar
Konuyu Açan #0
Custom Error Sınıfları Oluşturma

Bir yazılım projesinde, hele ki karmaşık iş mantıklarını barındıran veya dış servislerle yoğun etkileşimde olan bir sistemde, hataların yönetimi ve anlaşılması hayati öneme sahip. Çoğumuz, bir hata durumunda basitçe throw new Error('Bir şeyler ters gitti!') yazıp geçeriz. Ancak bu yaklaşım, uygulamanız büyüdükçe veya farklı hata türlerine özel tepkiler vermeniz gerektiğinde sürdürülemez bir hal alıyor. Hata mesajı string'ini ayrıştırmaya çalışmak, hem hataya açık hem de bakımı zor bir yöntem... Gerçekten de, "bir şeyler ters gitti" ifadesi, hatanın kökenini bulmak için çoğu zaman yetersiz kalıyor, değil mi? İşte tam bu noktada, özel hata sınıfları devreye giriyor ve kodunuzdaki hata yönetimini bambaşka bir seviyeye taşıyor.

Peki, neden standart Error nesnesi bize yetmiyor da kendi hata sınıflarımızı oluşturma ihtiyacı hissediyoruz? Aslında temel Error nesnesi, bir hatanın oluştuğunu belirtmek için mükemmel bir başlangıç noktasıdır. Ancak her hata aynı değildir. Bir kullanıcının bulunamaması, bir veritabanı bağlantı hatası, yetkilendirme sorunları veya geçersiz giriş verileri... Bunların hepsi farklı kökenlere sahip, farklı şekillerde ele alınması gereken durumlar. Standart bir Error nesnesiyle bu farklılıkları ayırt etmek için genellikle hata mesajının içeriğini incelememiz gerekir ki bu da kırılgan bir bağımlılık yaratır. Mesaj metninde yapılacak küçük bir değişiklik bile, hatayı yakalayan ve işleyen kodun bozulmasına neden olabilir. Bu durum, özellikle büyük ekiplerde veya uzun ömürlü projelerde ciddi sorunlara yol açabilir.

Özel Hata Sınıflarının Temel Mantığı

Özel hata sınıfları oluşturmanın arkasındaki temel fikir, her özel hata durumuna kendi "kimliğini" vermektir. Bu, hatayı yakaladığımızda, mesajını ayrıştırmaya gerek kalmadan, sadece tipine bakarak ne tür bir hata olduğunu anlamamızı sağlar. Çoğu modern programlama dilinde (JavaScript, TypeScript, C#, Java, Python vb.), bu işlem mevcut Error (veya Exception) sınıfından kalıtım alarak gerçekleştirilir. Böylece, temel hata nesnesinin tüm özelliklerini (mesaj, yığın izi gibi) korurken, üzerine kendi spesifik özelliklerimizi ve davranışlarımızı ekleyebiliriz.

Bir örnek üzerinden gidelim; JavaScript dünyasında bu konuyu ele alalım. Varsayılan Error sınıfımız var. Biz bunun üzerine kendi özel hata sınıflarımızı inşa edeceğiz.

CODE
1234567891011121314151617181920212223242526272829303132
// Temel uygulama hata sınıfımız
class AppError extends Error {
  constructor(message, statusCode = 500) {
    super(message); // Temel Error sınıfının constructor'ını çağırır
    this.name = this.constructor.name; // Hata adını sınıfın adıyla eşleştirir
    this.statusCode = statusCode; // HTTP durum kodu gibi özel bir özellik ekleyebiliriz
    Error.captureStackTrace(this, this.constructor); // Yığın izini yakalar
  }
}

// Kullanıcı bulunamadığında fırlatılacak özel hata
class NotFoundError extends AppError {
  constructor(message = 'Kaynak bulunamadı.') {
    super(message, 404); // Üst sınıfa mesaj ve 404 durum kodunu göndeririz
  }
}

// Yetkilendirme hatası
class UnauthorizedError extends AppError {
  constructor(message = 'Yetkilendirme başarısız.') {
    super(message, 401);
  }
}

// Geçersiz giriş verisi hatası
class ValidationError extends AppError {
  constructor(message = 'Geçersiz giriş verileri.', details = []) {
    super(message, 400);
    this.details = details; // Hatanın detaylarını tutmak için özel bir property
  }
}


Yukarıdaki örnekte, önce tüm uygulama hatalarımızın temelini oluşturacak bir AppError sınıfı tanımladık. Bu sınıf, standart Error sınıfından kalıtım alıyor ve ek olarak bir statusCode özelliği ile hata adını otomatik olarak belirleme mekanizması içeriyor. Ardından, NotFoundError, UnauthorizedError ve ValidationError gibi daha spesifik hata sınıflarını AppError'dan türettik. Her biri, kendi varsayılan mesajını ve HTTP durum kodunu belirliyor. ValidationError örneğinde olduğu gibi, hataya özel ek bilgiler (örneğin, hangi alanların geçersiz olduğunu belirten bir details dizisi) de ekleyebiliriz. Bu, hatayı yakalayan kodun sadece hatanın türünü değil, aynı zamanda hatanın bağlamını da daha iyi anlamasını sağlar.

Ne Zaman ve Nasıl Kullanmalıyız?

Özel hata sınıfları, uygulamanızın farklı katmanlarında veya iş mantıklarında belirli bir hataya özel işlem yapmanız gerektiğinde altın değerindedir.

  • API Hataları: Bir REST API geliştiriyorsanız, NotFoundError (404), BadRequestError (400), ForbiddenError (403) gibi HTTP durum kodlarıyla doğrudan eşleşen hatalar tanımlayarak API istemcilerine daha anlamlı yanıtlar dönebilirsiniz. Bu, API'nizin daha tutarlı ve anlaşılır olmasını sağlar.
  • Domain Spesifik Hatalar: İş mantığınızda belirli koşulların ihlal edildiği durumlar için. Örneğin, bir e-ticaret uygulamasında stokta ürün kalmadığında InsufficientStockError veya bir kullanıcının bakiyesi yetersiz olduğunda InsufficientBalanceError fırlatabilirsiniz. Bu tür hatalar, iş süreçlerinizin daha net bir şekilde modellenmesine yardımcı olur.
  • Veritabanı Hataları: Veritabanı işlemleri sırasında ortaya çıkabilecek spesifik hataları (örneğin, benzersiz anahtar ihlali için DuplicateEntryError) yakalayıp daha kullanıcı dostu mesajlara dönüştürebilirsiniz.
  • Doğrulama Hataları: Kullanıcı girdilerinin beklenen format veya kurallara uymadığı durumlarda ValidationError kullanmak, hangi alanların geçersiz olduğunu ve nedenini istemciye detaylı bir şekilde iletmenizi sağlar.

Peki, bu özel hata sınıflarını kodumuzda nasıl kullanacağız? Çok basit:

CODE
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
function getUser(userId) {
  // Diyelim ki veritabanından kullanıcıyı çekiyoruz
  const user = database.findUserById(userId); 

  if (!user) {
    throw new NotFoundError([icode]ID'si ${userId} olan kullanıcı bulunamadı.[/icode]);
  }

  return user;
}

function processOrder(orderId, userId) {
  const order = database.findOrderById(orderId);
  if (!order) {
    throw new NotFoundError([icode]ID'si ${orderId} olan sipariş bulunamadı.[/icode]);
  }

  if (order.userId !== userId) {
    throw new UnauthorizedError('Bu siparişi işlemeye yetkiniz yok.');
  }

  // Sipariş işleme mantığı...
  // Diyelim ki burada bir validasyon hatası oluştu
  const isValid = validateOrder(order);
  if (!isValid) {
    throw new ValidationError('Sipariş bilgileri eksik veya hatalı.', ['adres', 'telefon']);
  }

  return 'Sipariş başarıyla işlendi.';
}

// Hataları yakalama
try {
  const user = getUser('nonExistentUser123');
  console.log(user);
} catch (error) {
  if (error instanceof NotFoundError) {
    console.error([icode][API Hata - 404]: ${error.message} - Durum Kodu: ${error.statusCode}[/icode]);
    // İstemciye 404 yanıtı gönder
  } else if (error instanceof UnauthorizedError) {
    console.error([icode][API Hata - 401]: ${error.message} - Durum Kodu: ${error.statusCode}[/icode]);
    // İstemciye 401 yanıtı gönder
  } else if (error instanceof ValidationError) {
    console.error([icode][API Hata - 400]: ${error.message} - Detaylar: ${error.details.join(', ')} - Durum Kodu: ${error.statusCode}[/icode]);
    // İstemciye 400 yanıtı gönder, detayları da ekle
  } else if (error instanceof AppError) {
    console.error([icode][Uygulama Hata]: ${error.message} - Durum Kodu: ${error.statusCode}[/icode]);
    // Bilinmeyen uygulama hatası
  } else {
    console.error([icode][Beklenmedik Hata]: ${error.message}[/icode]);
    // Hiç yakalanmayan genel hata
  }
}


Gördüğünüz gibi, catch bloğunda instanceof operatörünü kullanarak hatanın türünü kolayca ayırt edebiliyoruz. Bu, her bir hata türüne özel işlem yapmamızı, örneğin farklı loglama stratejileri uygulamamızı, kullanıcıya farklı geri bildirimler sunmamızı veya API yanıtlarında farklı HTTP durum kodları döndürmemizi sağlıyor. Bu sayede, hatanın sadece oluştuğunu değil, ne tür bir hata olduğunu ve nasıl ele alınması gerektiğini de net bir şekilde belirtmiş oluyoruz. Bu, kodun okunabilirliğini ve bakımı kolaylığını inanılmaz derecede artırır. Hata ayıklama süreçleri de, spesifik hata sınıfları sayesinde çok daha hızlı ve verimli hale gelir. Artık "bir şeyler ters gitti" yerine, "kullanıcı bulunamadı" veya "yetkiniz yok" gibi net mesajlarla karşılaşıyoruz.

En İyi Uygulamalar ve Düşünülmesi Gerekenler

  1. Hata Hiyerarşisi Oluşturun: Tüm özel hata sınıflarınızın temel bir AppError (veya benzeri) sınıfından türemesini sağlayın. Bu, daha genel bir hata yakalama blo

Yanıt vermek için giriş yapmış olmalısınız.

0 alıntı seçildi