Bu Hata Neden Oluşur?
Bir gün bir Express.js uygulaması geliştirirken, API'nizin sonunda şöyle bir hata alabilirsiniz: "Cannot set headers after they are sent to the client". Hatanın tam anlamını açıklamadan önce, HTTP isteklerinin nasıl çalıştığını anlamak çok önemli.
Bu hatanın nedeni, yanıt başlıklarını (headers) istemciye göndermenin ardından tekrar bir başlık değiştirme işlemi yapmaya çalışmaktır. Eğer bir yanıtı bir kez göndermişseniz ve sonrasında başka başlıklar eklemeye çalışırsanız, Express.js size “Cannot set headers after they are sent to the client” şeklinde bir hata verir.
O Anki Durumu Hayal Edin
Bir gün, sabahın erken saatlerinde kod yazarken bir API oluşturuyorsunuz. Düşünüyorsunuz ki, her şey yolunda gidiyor. Ancak birden, bu başlık hatası ortaya çıkıyor ve kodu incelerken bir şeylerin ters gittiğini fark ediyorsunuz. Yanıtı birkaç kez göndermişsiniz ve Express.js “Bir hata var, başlıklar bir kez gönderildikten sonra başka başlıklar eklenemez!” diyor.
Hata Nerelerde Karşımıza Çıkar?
Hatanın en yaygın görüldüğü senaryolar şunlardır:
Bir endpoint içerisinde hem `res.send()` hem de `res.json()` gibi yanıt metotlarını ardışık olarak çağırmak bu hataya yol açabilir.
2. Asenkron Kod ve Yanıt Zamanlaması
Eğer asenkron bir işlem sonrasında yanıt gönderiyorsanız, bu işlem tamamlanmadan önce bir yanıt göndermeye çalışmak da bu hatayı tetikleyebilir.
Nasıl Çözülür?
Şimdi, bu hatayı nasıl çözebileceğinize bakalım. İki temel çözüm yolu vardır:
1. Yanıtı sadece bir kez gönderdiğinizden emin olun.
Kodunuzda birden fazla yanıt göndermediğinizden emin olun. `res.send()` veya `res.json()` gibi metodlar yalnızca bir kez çağrılmalıdır.
Asenkron işlemler yapıyorsanız, `await` ve `async` kullanarak işlemlerin sırasını düzgün bir şekilde kontrol edin. Böylece her şeyin sırası doğru olacak ve yanıtınızı yalnızca bir kez göndereceksiniz.
Örnek olarak:
kopyalaapp.get('/test', async (req, res) => { try { // Asenkron bir işlem yapıyoruz const result = await someAsyncFunction(); // Yanıtı bir kez gönderiyoruz res.json({ message: result }); } catch (error) { // Hata durumunda yanıtı bir kez gönderiyoruz res.status(500).json({ error: 'Bir hata oluştu' }); } });
Başka Çözüm Yöntemleri
Bir başka çözüm yolu ise, her olasılığı kontrol etmek ve yalnızca tek bir yanıt göndermek için koşullar kullanmaktır. Örneğin, bir hata oluştuğunda yanıt gönderdiğinizde, işlem devam etmeden önce başka bir yanıt göndermemek için koşul kullanabilirsiniz.
kopyalaapp.get('/data', (req, res) => { if (someCondition) { res.status(400).send('Geçersiz işlem'); return; // Başka bir işlem yapılmasını engelliyoruz } res.json({ data: 'Başka veriler' }); });
Bu gibi çözümler, yalnızca bir yanıt gönderilmesini sağlayarak hatayı engelleyecektir.