Express.js ile geliştirdiğiniz REST API'lerde hata yönetimi, uygulamanızın güvenilirliği ve bakımı için kritik öneme sahiptir. Merkezi bir hata yönetim middleware'i, her uç noktada tekrar eden try-catch bloklarından kurtulmanızı ve hataları standart bir formatta istemciye döndürmenizi sağlar. Bu yazıda, Express.js API'lerinde merkezi hata yönetimini adım adım nasıl kuracağınızı ve uygulama sırasında dikkat etmeniz gereken noktaları pratik ipuçları ve kontrol listesiyle öğreneceksiniz.
Neden Merkezi Hata Yönetimi?
Her route handler'da hata yönetimini ayrı ayrı yapmak, kod tekrarına ve tutarsız hata mesajlarına yol açar. Merkezi bir yaklaşım şu avantajları sunar:
- Kod tekrarını azaltır, bakımı kolaylaştırır.
- Tüm hataların tek bir noktada yakalanmasını sağlar.
- İstemciye dönen hata formatını standartlaştırır (örneğin,
{ "error": { "message": "...", "code": ... } }). - Hata loglama ve dışarıya bildirim gibi işlemleri merkezileştirir.
Adım 1: Temel Hata Sınıfları Oluşturun
Uygulamanızda farklı hata türlerini temsil eden sınıflar oluşturun. Örneğin, AppError adında bir temel sınıf ve ondan türeyen NotFoundError, ValidationError gibi alt sınıflar. Bu sayede hata kodlarını ve mesajlarını tutarlı hale getirirsiniz.
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
this.isOperational = true; // beklenen hatalar için işaret
Error.captureStackTrace(this, this.constructor);
}
}
class NotFoundError extends AppError {
constructor(message = 'Kaynak bulunamadı') {
super(message, 404);
}
}Adım 2: Global Hata Middleware'i Ekleyin
Express.js'de hata middleware'i dört parametre alır: (err, req, res, next). Bu middleware'i, route tanımlarınızdan sonra tanımlayın.
const errorHandler = (err, req, res, next) => {
let statusCode = err.statusCode || 500;
let message = err.message || 'Sunucu hatası';
// Beklenmeyen hatalarda (programlama hataları) 500 döndür
if (!err.isOperational) {
statusCode = 500;
message = 'Bir hata oluştu';
// Hata loglama servisi çağrılabilir
console.error('Unexpected Error:', err);
}
res.status(statusCode).json({
success: false,
error: {
message,
statusCode
}
});
};
module.exports = errorHandler;Bu middleware'i app.use(errorHandler) ile uygulamaya ekleyin.
Adım 3: Asenkron Hataları Yakalayın
Express.js 4.x'te asenkron fonksiyonlardaki hatalar otomatik olarak yakalanmaz. Bunun için bir yardımcı fonksiyon kullanabilirsiniz.
const catchAsync = (fn) => {
return (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
};
// Kullanımı:
app.get('/api/users', catchAsync(async (req, res) => {
const users = await User.find();
res.json({ success: true, data: users });
}));Express.js 5'te bu davranış varsayılan hale gelecek, ancak şimdilik bu yöntemi kullanın.
Adım 4: Hata Fırlatma Stratejileri
İş mantığınızda hata fırlatmak için oluşturduğunuz özel hata sınıflarını kullanın.
- Kaynak bulunamadığında
throw new NotFoundError(); - Doğrulama hatasında
throw new ValidationError('Geçersiz e-posta'); - Yetki hatasında
throw new UnauthorizedError();
Bu sayede global middleware'iniz hatayı yakalar ve uygun HTTP durum koduyla döner.
Adım 5: Hataları Loglama ve Dış Servislere İletme
Üretim ortamında hataları loglamak ve harici bir servise (Sentry, LogRocket vb.) iletmek önemlidir. Global middleware içinde bu işlemleri gerçekleştirebilirsiniz.
if (process.env.NODE_ENV === 'production') {
// Sentry gibi bir servise hata gönder
Sentry.captureException(err);
} else {
console.error(err.stack);
}Kontrol Listesi
- Özel hata sınıfları oluşturdunuz mu? (ör.
AppError) - Global hata middleware'ini route'lardan sonra tanımladınız mı?
- Asenkron hataları yakalamak için
catchAsyncyardımcısını kullanıyor musunuz? - Hataları standart bir JSON formatında dönüyor musunuz?
- Operasyonel olmayan hatalar için uygun loglama yapıyor musunuz?
- Hata sınıflarınızı
isOperationalile işaretlediniz mi? - Geliştirme ortamında hata stack trace'ini gösteriyor, üretimde gizliyor musunuz?
Yaygın Hatalar
- Middleware sırası: Hata middleware'ini route'lardan önce tanımlamak hataların yakalanmamasına yol açar. Her zaman en sona koyun.
- Her yerde try-catch:
catchAsynckullanmadığınızda her async route'da try-catch yazmak zorunda kalırsınız. Bu, kod tekrarını artırır. - Hata türü kontrolü:
err instanceof AppErrorgibi kontroller yaparak beklenen ve beklenmeyen hataları ayırın. - Express 5 uyarısı: Express 5 asenkron hataları otomatik yakalasa da, mevcut projelerde çoğunlukla Express 4 kullanıldığı için yukarıdaki yöntemler geçerlidir.
İleri Seviye: Katmanlı Hata Yönetimi
Büyük projelerde, farklı katmanlar (veritabanı, servis, controller) için ayrı hata sınıfları oluşturmak faydalı olabilir. Örneğin, DatabaseError, ServiceError gibi. Tüm bu sınıfları AppError temel sınıfından türetmek, tek bir global middleware ile yönetimi kolaylaştırır.
Express.js ile İlgili Diğer Kaynaklar
Merkezi hata yönetiminin yanı sıra, Express.js ile API geliştirirken performans ve mimari karşılaştırmaları da önemlidir. Express.js vs Fastify: Node.js API Geliştirme İçin Hangisi Daha İyi? yazımızda iki framework'ün hata yönetimi yaklaşımlarını da bulabilirsiniz. Ayrıca API versiyonlama stratejileri için API Versiyonlama Stratejileri yazımıza göz atabilirsiniz. Sayfalama stratejileriyle ilgili REST API Sayfalama Stratejileri yazısı da hata yönetimi ile birlikte kullanıldığında daha sağlam bir API sunar.
Sonuç
Merkezi hata yönetimi, Express.js API projelerinizde kod kalitesini artıran ve hata ayıklama sürecini kolaylaştıran bir yaklaşımdır. Bu rehberdeki adımları takip ederek, hataları tutarlı bir şekilde yakalayıp yönetebilir, uygulamanızı daha güvenilir hale getirebilirsiniz.
Sık Sorulan Sorular
Express.js'de hata middleware'i neden 4 parametre alır?
Express.js, 4 parametreli middleware'leri özel olarak hata middleware'i olarak tanır. Hata middleware'i (err, req, res, next) şeklinde tanımlandığında, bir hata oluştuğunda Express bu middleware'i çağırır.
catchAsync yardımcısı olmazsa ne olur?
Async fonksiyonlardaki hatalar otomatik olarak yakalanmaz ve Express'in varsayılan hata işleyicisine düşer, bu da genellikle sunucu kilitlenmesine veya isteğin yanıtsız kalmasına yol açar.
Hata sınıflarında isOperational ne işe yarar?
isOperational flag'i, hatanın beklenen (örneğin doğrulama hatası) mı yoksa beklenmeyen bir hata mı olduğunu ayırt etmek için kullanılır. Beklenmeyen hatalar genellikle 500 döndürülürken, operasyonel hatalar uygun durum kodlarıyla döner.
Global hata middleware'i nereye eklenmeli?
Global hata middleware'i, tüm route tanımlarından ve diğer middleware'lerden sonra (app.use(errorHandler)) eklenmelidir. Aksi takdirde hatalar yakalanmaz.






