Node.js + Express.js uygulamaları için hata işleme ilkeleri?


177

Hata raporlaması / işlemesi, Node.js + Express.js uygulamalarında diğer çerçevelere göre farklı şekilde yapılır gibi görünüyor . Aşağıdaki gibi çalıştığını anlamakta doğru muyum?

A) Hataları, geri arama işlevlerinize parametre olarak alarak tespit edin. Örneğin:

doSomethingAndRunCallback(function(err) { 
    if(err) {  }
});

B) Rapor sonraki çağırarak (err) tarafından ortakatmanlarına hatalar. Misal:

handleRequest(req, res, next) {
    // An error occurs…
    next(err);
}

C) Rapor hatasını atarak YOLLARI hatalar. Misal:

app.get('/home', function(req, res) {
    // An error occurs
    throw err;
});

D) Kol app.error kullanarak kendi hata işleyicisi yapılandırarak hataları () veya genel Bağlan hata işleyicisi kullanın. Misal:

app.error(function(err, req, res, next) {
    console.error(err);
    res.send('Fail Whale, yo.');
});

Bu dört ilke Node.js + Express.js uygulamalarındaki tüm hataların ele alınması / raporlanması için temel oluşturuyor mu?

Yanıtlar:


183

Node.js dosyasında hata işleme genellikle A) biçimindedir. Çoğu geri arama ilk argüman olarak bir hata nesnesi döndürür null.

Express.js ara katman yazılımı ve ara katman yazılımı sözdizimi B) ve E) kullanır (aşağıda belirtilmiştir).

C) bana sorarsanız kötü bir uygulamadır.

app.get('/home', function(req, res) {
    // An error occurs
    throw err;
});

Yukarıdakileri kolayca yeniden yazabilirsiniz.

app.get('/home', function(req, res, next) {
    // An error occurs
    next(err);
});

Ara katman yazılımı söz dizimi bir getistekte geçerlidir .

D gelince)

(07:26:37) tjholowaychuk: uygulama hatası 3.x'te kaldırıldı

TJ app.error, E lehine onaylanmadığını doğruladı

E)

app.use(function(err, req, res, next) {
  // Only handle `next(err)` calls
});

Uzunluğu 4 (4 bağımsız değişken) olan herhangi bir ara katman yazılımı hata ara katmanı olarak kabul edilir. Bir çağrı next(err)bağlandığında gider ve hata tabanlı ara katman yazılımlarını çağırır.


11
Teşekkürler! Gelecekte bununla karşılaşabilen herkes için, "yöntem e" için parametrelerin sırası aslında err, req, res, next (req, res, next, err yerine) gibi görünüyor.
Clint Harris

9
Bu harika görünüyor, ancak gördüğüm bir sorun, bazı hataların asla tanımladığınız hata işleyicilerine yol açmaması ve yalnızca bir process.on ('uncaughtException', fn) işleyicisi tarafından yakalanabilmesidir. Geleneksel bilgelik bunun olmasına izin vermek ve uygulamayı yeniden başlatmak için Forever veya benzerlerine güvenmektir, ancak bunu yaparsanız, dostça bir hata sayfasını nasıl iade edersiniz?
Paul

1
@chovy Ayrıca, sadece bir fyi. Hata işleyici atılan / sonraki hatadan sonra uygulamaya verilmelidir . Daha önce varsa, hatayı yakalamaz.
Lee Olayvar

3
next (err) aslında Express'in bir hata atma sürümüdür, bunu açıkça kendi ara yazılımınızda çağırmanız gerekir
qodeninja

1
@qodeninja Bu yöntem Express'te en iyi uygulama olarak kabul edilir.
David Oliveros

11

Joyent'teki insanlar bu konuda gerçekten iyi anlaşılır en iyi uygulamalar belgesi yayınladılar. Herhangi bir Node.js geliştiricisi için okunması gereken bir makale.



Harika makale, bağlantıyı Joyent'in güncellenmiş belgesine işaret edecek şekilde düzeltti.
stephbu

2
makale fena değil: ama çok fazla metin ve yeterli örnek değil gerçek profesyoneller için bir makale
Gerd

3

Neden ilk parametre?

Node.js'nin eşzamansız yapısı nedeniyle, err parametresi olarak ilk parametre deseni, kullanıcı ülkesi Node.js hatalarının işlenmesi için bir kural olarak iyi anlaşılmıştır . Bunun nedeni eşzamansız:

try {
    setTimeout(function() {
        throw 'something broke' //Some random error
    }, 5)
}
catch(e) {
   //Will never get caught
}

Bu nedenle, bunun yerine, geri çağrının ilk argümanına sahip olmak, hataları atmaktan başka zaman uyumsuz olarak geçirmenin tek mantıklı yoludur.

Bunu yapmak unhandled exception, sadece göründüğü gibi, uygulamayı şaşkın durumundan çıkarmak için hiçbir şeyin yapılmadığı anlamına gelecektir.

İstisnalar, neden varlar

Bununla birlikte, Node.js'nin neredeyse tüm bölümlerinin olay yayıcıları olduğunu ve bir istisnanın atılmasının, tüm olaylar gibi ele alınabilen düşük seviyeli bir olay olduğunu belirtmek gerekir:

//This won't immediately crash if connection fails
var socket = require("net").createConnection(5000);
socket.on("error", function(err) {
    console.error("calm down...", err)
});

Bu , tüm hataları yakalamak ve asla çökmemesi için çok çaba gösterecek bir uygulama yapmak için aşırıya götürülmemelidir . Bu hemen hemen her kullanım durumunda korkunç bir fikirdir, çünkü uygulama durumunda neler olup bittiğine dair herhangi bir fikir olmadan geliştiriciden ayrılacak ve try-catch'de ana sarmalamaya benzer.

Alanlar - etkinlikleri mantıksal olarak gruplama

Uygulamaların devrilmesine neden olan bu istisnalar sorunuyla ilgilenmenin bir parçası olarak, alanlar geliştiricinin örneğin Express.js uygulamasını almasına ve felaket başarısızlığı durumunda bağlantıları makul bir şekilde kapatmaya çalışmasına izin verir.

ES6

ES6'nın jeneratör deseninin hala dene / yakala bloklarıyla toplanabilir eşzamansız olaylar oluşturmasına izin verdiği için bunun tekrar değişeceğinden bahsediyoruz.

Koa (Express.js'nin aynı orijinal yazarı TJ Holowaychuck tarafından yazılmıştır) bunu açıkça yapıyor. ES6 yielddeyimini kullanarak, neredeyse senkronize görünmekle birlikte, normal düğüm asenkronize olarak işlenen bloklar oluşturmak için kullanır :

app.use(function *(next) {
    try {
        yield next;
    } 
    catch (err) {
        this.status = err.status || 500;
        this.body = err.message;
        this.app.emit('error', err, this);
    }
});

app.use(function *(next) {
    throw new Error('some error');
})

Bu örnek utanmadan buradan çalınmıştı .

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.