Kullanım durumum, REST API'mi güçlendirmek için ekspres kullandığım için özel bir JSON hata mesajı gönderiyor. Bunun oldukça yaygın bir senaryo olduğunu düşünüyorum, bu yüzden cevabımda buna odaklanacağım.
Kısa versiyon:
Ekspres Hata İşleme
Hata işleme ara yazılımını, özellikle imza ile (err, req, res, next) üç yerine dört bağımsız değişken dışında diğer ara yazılımlar gibi tanımlayın. ... Hata işleme ara yazılımını en son, diğer app.use () kullanımından sonra tanımlar ve çağrıları yönlendirirsiniz
app.use(function(err, req, res, next) {
if (err instanceof JSONError) {
res.status(err.status).json({
status: err.status,
message: err.message
});
} else {
next(err);
}
});
Şunları yaparak koddaki herhangi bir noktadan hataları artırın:
var JSONError = require('./JSONError');
var err = new JSONError(404, 'Uh oh! Can't find something');
next(err);
Uzun versiyon
Hataları atmanın kanonik yolu şudur:
var err = new Error("Uh oh! Can't find something");
err.status = 404;
next(err)
Varsayılan olarak, Express bunu, 404 kodlu bir HTTP Yanıtı olarak düzgün bir şekilde paketleyerek ve bir yığın izleme eklenmiş mesaj dizesinden oluşan bir gövdeyle ele alır.
Örneğin, Express'i bir REST sunucusu olarak kullandığımda bu benim için çalışmıyor. Hatanın HTML olarak değil, JSON olarak geri gönderilmesini istiyorum. Ayrıca yığın izimin müşterime taşınmasını da kesinlikle istemiyorum.
JSON'ı req.json()örneğin kullanarak yanıt olarak gönderebilirim . gibi bir şey req.json({ status: 404, message: 'Uh oh! Can't find something'}). İsteğe bağlı olarak, ile durum kodunu ayarlayabilirim req.status(). İkisini birleştirmek:
req.status(404).json({ status: 404, message: 'Uh oh! Can't find something'});
Bu bir cazibe gibi çalışıyor. Bununla birlikte, her hata aldığımda yazmayı oldukça güç buluyorum ve kod artık bizimki gibi kendi kendini belgelemiyor next(err). Normal (yani geçerli) bir JSON yanıtının gönderilme şekline çok benziyor. Ayrıca, kanonik yaklaşım tarafından atılan tüm hatalar yine de HTML çıktısıyla sonuçlanır.
Express'in hata işleme ara yazılımı burada devreye girer. Rotalarımın bir parçası olarak şunları tanımlarım:
app.use(function(err, req, res, next) {
console.log('Someone tried to throw an error response');
});
Ayrıca Error sınıfını özel bir JSONError sınıfına alıyorum:
JSONError = function (status, message) {
Error.prototype.constructor.call(this, status + ': ' + message);
this.status = status;
this.message = message;
};
JSONError.prototype = Object.create(Error);
JSONError.prototype.constructor = JSONError;
Şimdi, koda bir Hata atmak istediğimde, şunu yapıyorum:
var err = new JSONError(404, 'Uh oh! Can't find something');
next(err);
Özel hata işleme ara yazılımına geri dönersek, bunu şu şekilde değiştiriyorum:
app.use(function(err, req, res, next) {
if (err instanceof JSONError) {
res.status(err.status).json({
status: err.status,
message: err.message
});
} else {
next(err);
}
}
Hatayı JSONError'a alt sınıflandırma önemlidir, zira Express'in normal bir işleyicinin mi yoksa bir hata işleyicinin mi çağrılması gerektiğini belirlemek instanceof Erroriçin a'ya geçirilen ilk parametre üzerinde bir kontrol yaptığından şüpheleniyorum next(). instanceof JSONErrorBeklenmeyen hataların (çökme gibi) ayrıca bir JSON yanıtı döndürmesini sağlamak için denetimi kaldırabilir ve küçük değişiklikler yapabilirim.