Node.js UnhandledPromiseRejectionWarning'de hangi vaatlerin yerine getirilmediğini nasıl bulabilirim?


177

Sürüm 7'deki Node.js, vaatleri yerine getirmek için asenkronize / sözdizimsel şeker bekliyor ve şimdi kodumda aşağıdaki uyarı oldukça sık geliyor:

(node:11057) UnhandledPromiseRejectionWarning: Unhandled promise 
rejection (rejection id: 1): ReferenceError: Error: Can't set headers 
after they are sent.
(node:11057) DeprecationWarning: Unhandled promise rejections are 
deprecated. In the future, promise rejections that are not handled 
will terminate the Node.js process with a non-zero exit code.

Ne yazık ki, yakalamanın eksik olduğu çizgiye referans yok. Her try / catch bloğunu kontrol etmeden bulmanın bir yolu var mı?


Bluebird vaat kütüphanesini kullanabilirsiniz ve muhtemelen bir yığın izlemesi verir.
jfriend00

3
Belki Düğümün unhandledRejectionetkinliğine kaydolmak yardımcı olacaktır? Belgelere bakın . Geri arama Errornesneyi ve gerçek alır ve nesne bir yığın izleme tutabilir Promiseinanıyorum Error.
YSK

Önceki iki yorum yardımcı olmazsa, Can't set headers after they are sent.kodunuzda nerede olabileceğine dair bir ipucu vermelidir (örneğin, muhtemelen eşzamansız kodu anlamada başarısız olmasından dolayı, üstbilgiler zaten gönderildikten sonra üstbilgileri ayarladığınız bir yere). , ama bu bir tahmin)
Jaromanda X

merhaba mesajlar hata kodun nerede olduğunu bulmak için yardımcı olur, btw satır bilmek kadar kolay değil.
user1658162

1
@ jfriend00 Bu, zaman uyumsuz bir fonksiyonun hata attığı bir durumdu - zaman uyumsuz fonksiyonlar için bu iç Düğüm vaatleri Bluebird kullanmıyor, bu yüzden Bluebird'e sahip olmak bu senaryoda yardımcı olmuyor.
Adam Reis

Yanıtlar:


297

unhandledRejectionsüreç olayını dinle .

process.on('unhandledRejection', (reason, p) => {
  console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
  // application specific logging, throwing an error, or other logic here
});

35
Günlüğe kaydetme error.stack(veya yukarıdaki örnekte reason.stack), hatanın tam yığın izlemesini verir.
Adam Reis

Bulduğum diğer birçok örnekte process.onolduğu server.ongibi koymak yerine teşekkür ederiz
PhillipHolmes

9
Keşke bunun işe yaradığını söyleyebilseydim, ama olmadı. 8.9.4 düğümündeyim.
ffxsam

2
Yukarıdaki kodu denedim ve her iki nedenle de tanımsız var ve p? Baska öneri? "İşlenmeyen Reddetme: Promise {durum: 'reddedildi', nedeni: tanımsız} nedeni: tanımsız"
Jeremy

3
Bu kodu düğüm dosyamın üstüne ekledim app.jsve hiçbir şey maalesef günlüğe kaydedilmedi. Düğüm v10.13.0.
user1063287

71

Doğru işlenmeyen ES6 Promise ret için tam stacktrace göstermek için yolu ile node.js çalıştırmaktır --trace-warningsbayrak. Bu, kendi kodunuzdaki reddetmeyi durdurmak zorunda kalmadan, her uyarı için tam yığın izini gösterecektir. Örneğin:

düğüm - trace-warnings app.js

trace-warningsBayrağın dosyanızın adından önce geldiğinden emin olun .js! Aksi takdirde, bayrak komut dosyanız için bir argüman olarak yorumlanır ve Node.js'nin kendisi tarafından yoksayılır.

İşlenmeyen reddetmeleri gerçekten işlemek istiyorsanız (ör. Bunları günlüğe kaydederek), unhandled-rejectionbunun yerine modülümüzü kullanmak isteyebilirsiniz , bu da onu destekleyen her büyük Promises uygulaması için tek bir olay işleyiciyle tüm işlenmemiş reddetmeleri yakalar.

Bu modül destekleri Bluebird, ES6 Sözler, Q, WhenJS, es6-promise, then/promiseve bir şey olduğunu işlenmeyen ret özelliklerine (belgelerinde tüm ayrıntıları) herhangi birine uygundur.


20
7.8.0 düğümü ve tüm bunları bana kullanmak, bir dizi iç düğüm modülü için yığın izlemesidir. (düğüm: 10372) UnhandledPromiseRejectionWarning: emitPendingUnhandledRejections'da (internal / process / promises.js: 59: 21) emitPendingUnhandledRejections'da (internal / process / promises.js: 59: 21) işlenmemiş ._tickDomainCallback (dahili / süreç / next_tick.js: 136: 7)
Will Lovett

3
İşlenmemiş söz konusu sorunun nerede olduğunu gösteren herhangi bir çıktı görmüyorum.
Jason Leach

package.jsonKomut dosyasını başlatmak için bunu ekledim ve maalesef hiçbir şey kaydedilmedi. Düğüm v10.13.0.
user1063287

1
@ user1063287 Bayrağın komutunuzda doğru yerde olduğundan emin olun. Sadece komut dosyasının adından önce gitmesi gerektiğini vurgulamak için cevaba bir güncelleme ekledim .
Sven Slootweg

2
Muhtemelen orijinal işlenmemiş hatanın ( kullanımdan kaldırma uyarısının üzerinde bir yerde olması gerekir) değil, kullanımdan çıkarma uyarısının yığın izine bakıyorsunuzdur .
Sven Slootweg

7

Yığın izleme ile günlük kaydı

Yararlı bir hata mesajı daha arıyorsanız. Bunu düğüm dosyanıza eklemeyi deneyin. Kilitlenmenin gerçekleştiği yerde tam yığın izini görüntülemelidir.

process.on('unhandledRejection', (error, p) => {
  console.log('=== UNHANDLED REJECTION ===');
  console.dir(error.stack);
});

Tek işlevsel fark, hatanın stack özelliğinde bir console.dir yapmaktır. Çıktıda kabul edilen cevaba kıyasla oldukça fark var.
joshuakcockrell
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.