Kasus penggunaan saya mengirimkan pesan kesalahan JSON khusus, karena saya menggunakan express untuk memberdayakan REST API saya. Saya pikir ini adalah skenario yang cukup umum, jadi fokuslah pada jawaban saya.
Versi pendek:
Penanganan Kesalahan Ekspres
Definisikan middleware penanganan kesalahan seperti middleware lainnya, kecuali dengan empat argumen, bukan tiga, khususnya dengan tanda tangan (err, req, res, next). ... Anda menentukan penanganan kesalahan middleware terakhir, setelah app.use () lain dan merutekan panggilan
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);
}
});
Tingkatkan kesalahan dari titik mana pun dalam kode dengan melakukan:
var JSONError = require('./JSONError');
var err = new JSONError(404, 'Uh oh! Can't find something');
next(err);
Versi Panjang
Cara kanonik untuk melempar kesalahan adalah:
var err = new Error("Uh oh! Can't find something");
err.status = 404;
next(err)
Secara default, Express menangani ini dengan mengemasnya secara rapi sebagai Respons HTTP dengan kode 404, dan isi yang terdiri dari string pesan yang ditambahkan dengan jejak tumpukan.
Ini tidak berfungsi untuk saya ketika saya menggunakan Express sebagai server REST, misalnya. Saya ingin kesalahan dikirim kembali sebagai JSON, bukan sebagai HTML. Saya juga pasti tidak ingin pelacakan tumpukan saya dipindahkan ke klien saya.
Saya dapat mengirim JSON sebagai tanggapan menggunakan req.json()
, misalnya. sesuatu seperti req.json({ status: 404, message: 'Uh oh! Can't find something'})
. Secara opsional, saya dapat mengatur kode status menggunakan req.status()
. Menggabungkan keduanya:
req.status(404).json({ status: 404, message: 'Uh oh! Can't find something'});
Ini bekerja seperti pesona. Karena itu, saya merasa cukup sulit untuk mengetik setiap kali saya mengalami kesalahan, dan kodenya tidak lagi mendokumentasikan diri seperti next(err)
sebelumnya. Ini terlihat terlalu mirip dengan bagaimana JSON respon normal (yaitu, valid) dikirim. Lebih lanjut, kesalahan apa pun yang dilemparkan oleh pendekatan kanonik masih menghasilkan keluaran HTML.
Di sinilah middleware penanganan kesalahan Express masuk. Sebagai bagian dari rute saya, saya mendefinisikan:
app.use(function(err, req, res, next) {
console.log('Someone tried to throw an error response');
});
Saya juga membuat subclass Error menjadi kelas JSONError kustom:
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;
Sekarang, ketika saya ingin menampilkan Error pada kode, saya lakukan:
var err = new JSONError(404, 'Uh oh! Can't find something');
next(err);
Kembali ke middleware penanganan kesalahan khusus, saya memodifikasinya menjadi:
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);
}
}
Subclassing Error ke JSONError penting, karena saya menduga Express melakukan instanceof Error
pemeriksaan pada parameter pertama yang diteruskan ke a next()
untuk menentukan apakah penangan normal atau penangan kesalahan harus dipanggil. Saya dapat menghapus instanceof JSONError
centang dan membuat modifikasi kecil untuk memastikan kesalahan tak terduga (seperti crash) juga mengembalikan respons JSON.