Bvural41 1
Bvural41
Hikaye Ekle

[NODE JS] try-catch ile Hata Yakalama

nodejs.png


[NODE JS] try-catch ile Hata Yakalama​


Selam arkadaşlar. Hata yakalama, yazılım geliştirmenin en kritik konularından biri. "Happy path" yazması kolay, asıl zorluk hataları düzgün yönetmek. Ben production'da yaşadığım en büyük sorunların çoğu düzgün hata yönetimi yapılmamış kodlardan kaynaklanıyordu. Bugün try-catch mekanizmasını detaylıca anlatacağım.

try-catch Temelleri​


try bloğu içinde potansiyel olarak hata verebilecek kodları yazarız. Hata oluşursa catch bloğu devreye girer. finally bloğu ise hata olsun olmasın her durumda çalışır. Bu üç blok birlikte kullanıldığında sağlam bir hata yönetimi altyapısı oluşturur.

Yeni başlayanlar bazen her şeyi tek bir büyük try-catch'e sarar ve catch'te sadece console.log yapar. Bu çok kötü bir pratik. Hataları anlamlı şekilde yönetmek gerekiyor: loglamak, kullanıcıya uygun mesaj göstermek, gerekirse tekrar denemek.

JavaScript:
// === TRY-CATCH TEMELLERİ ===

// Temel kullanım
try {
    const veri = JSON.parse('{"isim": "Ahmet", "yas": 28}');
    console.log('Başarılı:', veri);
} catch (hata) {
    console.error('JSON parse hatası:', hata.message);
}

// Hatalı JSON
try {
    const veri = JSON.parse('{geçersiz json}');
} catch (hata) {
    console.error('Hata türü:', hata.constructor.name); // SyntaxError
    console.error('Hata mesajı:', hata.message);
}

// finally bloğu
function dosyaOku(dosyaAdi) {
    let baglanti = null;
    try {
        console.log(`${dosyaAdi} açılıyor...`);
        baglanti = { dosya: dosyaAdi, acik: true };

        if (dosyaAdi === 'yok.txt') {
            throw new Error('Dosya bulunamadı');
        }

        console.log('Dosya başarıyla okundu');
        return baglanti;
    } catch (hata) {
        console.error(`Hata: ${hata.message}`);
        return null;
    } finally {
        // Her durumda çalışır (return olsa bile!)
        if (baglanti && baglanti.acik) {
            console.log('Bağlantı kapatılıyor (finally)');
            baglanti.acik = false;
        }
    }
}

dosyaOku('rapor.txt');
dosyaOku('yok.txt');

// Hata nesnesi özellikleri
try {
    undeclaredVariable.property; // ReferenceError
} catch (hata) {
    console.log('
--- Hata Detayları ---');
    console.log('name:', hata.name);           // ReferenceError
    console.log('message:', hata.message);     // undeclaredVariable is not defined
    console.log('stack:', hata.stack);          // Stack trace
}

// Birden fazla hata türünü ayırt etme
function veriIsle(girdi) {
    try {
        if (girdi === null) {
            throw new TypeError('Girdi null olamaz');
        }
        if (typeof girdi !== 'string') {
            throw new TypeError('Girdi string olmalı');
        }
        if (girdi.length === 0) {
            throw new RangeError('Girdi boş olamaz');
        }

        const sonuc = JSON.parse(girdi);
        return { basarili: true, veri: sonuc };
    } catch (hata) {
        if (hata instanceof TypeError) {
            console.error('Tip hatası:', hata.message);
        } else if (hata instanceof RangeError) {
            console.error('Aralık hatası:', hata.message);
        } else if (hata instanceof SyntaxError) {
            console.error('JSON sözdizimi hatası:', hata.message);
        } else {
            console.error('Beklenmeyen hata:', hata.message);
        }
        return { basarili: false, hata: hata.message };
    }
}

console.log(veriIsle(null));
console.log(veriIsle(42));
console.log(veriIsle(''));
console.log(veriIsle('{invalid}'));
console.log(veriIsle('{"valid": true}'));

Asenkron Hata Yönetimi​


Node.js'te en çok karşılaşılan senaryo asenkron hata yönetimidir. try-catch normal callback'lerde çalışmaz çünkü callback farklı bir execution context'te çalışır. Ama async/await ile try-catch tekrar kullanılabilir hale gelir. Bu yüzden modern Node.js'te async/await tercih ediyorum.

Production'da unhandled promise rejection ciddi sorunlara yol açar. Node.js 15'ten itibaren yakalanmamış promise rejection'lar uygulamayı çökertebilir. Bu yüzden her async fonksiyonu try-catch ile sarmak veya .catch() eklemek şart.

JavaScript:
// === ASENKRON HATA YÖNETİMİ ===

// Promise ile hata yakalama
function apiCagri(url) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (url.includes('error')) {
                reject(new Error(`API hatası: ${url}`));
            } else {
                resolve({ data: 'Başarılı yanıt', url });
            }
        }, 100);
    });
}

// .then/.catch ile
apiCagri('/api/kullanicilar')
    .then(yanit => console.log('Promise başarılı:', yanit))
    .catch(hata => console.error('Promise hatası:', hata.message));

// async/await ile try-catch
async function veriGetir() {
    try {
        const yanit1 = await apiCagri('/api/urunler');
        console.log('Yanıt 1:', yanit1);

        const yanit2 = await apiCagri('/api/error-endpoint');
        console.log('Yanıt 2:', yanit2); // Buraya ulaşılmaz
    } catch (hata) {
        console.error('Async hata:', hata.message);
    } finally {
        console.log('İşlem tamamlandı (başarılı veya başarısız)');
    }
}

veriGetir();

// Birden fazla Promise hatası
async function cokluIstek() {
    try {
        const sonuclar = await Promise.all([
            apiCagri('/api/a'),
            apiCagri('/api/b'),
            apiCagri('/api/c')
        ]);
        console.log('Tüm istekler başarılı:', sonuclar);
    } catch (hata) {
        console.error('En az bir istek başarısız:', hata.message);
    }
}

// Promise.allSettled ile tüm sonuçları alma (hata olsa bile)
async function guvenliBatch() {
    const sonuclar = await Promise.allSettled([
        apiCagri('/api/basarili'),
        apiCagri('/api/error-test'),
        apiCagri('/api/diger')
    ]);

    sonuclar.forEach((sonuc, i) => {
        if (sonuc.status === 'fulfilled') {
            console.log(`İstek ${i + 1}: Başarılı -`, sonuc.value);
        } else {
            console.log(`İstek ${i + 1}: Başarısız -`, sonuc.reason.message);
        }
    });
}

// Global hata yakalama (production'da önemli!)
process.on('uncaughtException', (hata) => {
    console.error('Yakalanmamış istisna:', hata.message);
    // Loglama yap, bildirim gönder, graceful shutdown
    // process.exit(1); // Production'da uygulamayı yeniden başlat
});

process.on('unhandledRejection', (sebep, promise) => {
    console.error('Yakalanmamış promise rejection:', sebep);
    // Loglama yap
});

setTimeout(() => {
    cokluIstek();
    guvenliBatch();
}, 500);

Hata yönetimi konusunu ciddiye alın. Production'da hatalar kaçınılmaz, önemli olan onları düzgün yakalamak ve yönetmek. Her async fonksiyonda try-catch kullanın, global error handler kurun ve hataları anlamlı şekilde loglayın. Kolay gelsin.
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst