Aplikasi node.js saya dimodelkan seperti aplikasi express / example / mvc .
Dalam aksi kontroler saya ingin mengeluarkan status HTTP 400 dengan pesan http khusus. Secara default, pesan status http adalah "Permintaan Buruk":
HTTP/1.1 400 Bad Request
Tapi saya ingin mengirim
HTTP/1.1 400 Current password does not match
Saya mencoba berbagai cara tetapi tidak ada yang mengatur pesan status http ke pesan khusus saya.
Fungsi pengontrol solusi saya saat ini terlihat seperti itu:
exports.check = function( req, res) {
if( req.param( 'val')!=='testme') {
res.writeHead( 400, 'Current password does not match', {'content-type' : 'text/plain'});
res.end( 'Current value does not match');
return;
}
// ...
}
Semuanya bekerja dengan baik tapi ... sepertinya bukan cara yang tepat untuk melakukannya.
Apakah ada cara yang lebih baik untuk menyetel pesan status http menggunakan ekspres?
Jawaban:
Anda dapat memeriksa dokumen
res.send(400, 'Current password does not match')
Look express 3.x ini untuk mengetahui detailnyaUPDATE untuk Expressjs 4.x
Gunakan cara ini (lihat dokumen Express 4.x ):
res.status(400).send('Current password does not match'); // or res.status(400); res.send('Current password does not match');
sumber
res.status(400).send('Current password does not match');
contoh bekerja untuk saya untuk Express 4.Express ^4.16.2
Tak satu pun dari jawaban yang ada mencapai apa yang diminta OP pada awalnya, yaitu menimpa Frase-Alasan default (teks yang muncul segera setelah kode status) yang dikirim oleh Express.
Apa yang kamu inginkan adalah
res.statusMessage
. Ini bukan bagian dari Express, ini adalah properti dari objek http.Response yang mendasari di Node.js 0.11+.Anda dapat menggunakannya seperti ini (diuji di Express 4.x):
function(req, res) { res.statusMessage = "Current password does not match"; res.status(400).end(); }
Kemudian gunakan
curl
untuk memverifikasi bahwa itu berfungsi:$ curl -i -s http://localhost:3100/ HTTP/1.1 400 Current password does not match X-Powered-By: Express Date: Fri, 08 Apr 2016 19:04:35 GMT Connection: keep-alive Content-Length: 0
sumber
statusMessage
ke sesuatu selain pesan standar yang dipetakan ke StatusCoderes.nativeResponse.statusMessage
Di sisi server (middleware Express):
if(err) return res.status(500).end('User already exists.');
Tangani di sisi Klien
Sudut: -
$http()..... .error(function(data, status) { console.error('Repos error', status, data);//"Repos error" 500 "User already exists." });
jQuery: -
$.ajax({ type: "post", url: url, success: function (data, text) { }, error: function (request, status, error) { alert(request.responseText); } });
sumber
Satu cara elegan untuk menangani kesalahan khusus seperti ini secara cepat adalah:
function errorHandler(err, req, res, next) { var code = err.code; var message = err.message; res.writeHead(code, message, {'content-type' : 'text/plain'}); res.end(message); }
(Anda juga dapat menggunakan express 'built-in express.errorHandler untuk ini)
Kemudian di middleware Anda, sebelum rute Anda:
Lalu di mana Anda ingin membuat kesalahan 'Kata sandi saat ini tidak cocok':
function checkPassword(req, res, next) { // check password, fails: var err = new Error('Current password does not match'); err.code = 400; // forward control on to the next registered error handler: return next(err); }
sumber
Anda bisa menggunakannya seperti ini
return res.status(400).json({'error':'User already exists.'});
sumber
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
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 sepertireq.json({ status: 404, message: 'Uh oh! Can't find something'})
. Secara opsional, saya dapat mengatur kode status menggunakanreq.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 anext()
untuk menentukan apakah penangan normal atau penangan kesalahan harus dipanggil. Saya dapat menghapusinstanceof JSONError
centang dan membuat modifikasi kecil untuk memastikan kesalahan tak terduga (seperti crash) juga mengembalikan respons JSON.sumber
Saat menggunakan Axios, Anda dapat mengambil pesan respons kustom dengan:
Axios.get(“your_url”) .then(data => { ... do something }.catch( err => { console.log(err.response.data) // you want this })
... setelah mengaturnya di Express sebagai:
res.status(400).send(“your custom message”)
sumber
Jika tujuan Anda hanya untuk menguranginya menjadi satu baris / sederhana, Anda dapat mengandalkan sedikit default ...
return res.end(res.writeHead(400, 'Current password does not match'));
sumber
Nah dalam kasus Restify kita harus menggunakan
sendRaw()
metodeSintaksnya adalah:
res.sendRaw(200, 'Operation was Successful', <some Header Data> or null)
sumber