Trường hợp sử dụng của tôi đang gửi thông báo lỗi JSON tùy chỉnh, vì tôi đang sử dụng express để cấp nguồn cho API REST của mình. Tôi nghĩ đây là một kịch bản khá phổ biến, vì vậy tôi sẽ tập trung vào điều đó trong câu trả lời của tôi.
Phiên bản ngắn:
Xử lý lỗi nhanh
Xác định phần mềm trung gian xử lý lỗi như các phần mềm trung gian khác, ngoại trừ với bốn đối số thay vì ba, cụ thể là với chữ ký (err, req, res, next). ... Bạn xác định phần mềm trung gian xử lý lỗi sau cùng, sau các cuộc gọi app.use () và định tuyến khác
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);
}
});
Tăng lỗi từ bất kỳ điểm nào trong mã bằng cách thực hiện:
var JSONError = require('./JSONError');
var err = new JSONError(404, 'Uh oh! Can't find something');
next(err);
Phiên bản dài
Cách ném lỗi thông thường là:
var err = new Error("Uh oh! Can't find something");
err.status = 404;
next(err)
Theo mặc định, Express xử lý điều này bằng cách đóng gói gọn gàng nó dưới dạng Phản hồi HTTP với mã 404 và nội dung bao gồm chuỗi thông báo được nối với dấu vết ngăn xếp.
Điều này không hiệu quả với tôi khi tôi đang sử dụng Express làm máy chủ REST chẳng hạn. Tôi muốn lỗi được gửi lại dưới dạng JSON, không phải dưới dạng HTML. Tôi cũng chắc chắn không muốn dấu vết ngăn xếp của tôi chuyển sang khách hàng của tôi.
Tôi có thể gửi JSON dưới dạng phản hồi bằng cách sử dụng req.json()
, ví dụ: đại loại như req.json({ status: 404, message: 'Uh oh! Can't find something'})
. Theo tùy chọn, tôi có thể đặt mã trạng thái bằng cách sử dụng req.status()
. Kết hợp cả hai:
req.status(404).json({ status: 404, message: 'Uh oh! Can't find something'});
Công việc này như một cái duyên vậy. Điều đó nói rằng, tôi thấy khá khó sử dụng khi nhập mỗi khi gặp lỗi và mã không còn tự ghi lại như trước đây next(err)
nữa. Nó trông quá giống với cách gửi một phản hồi bình thường (tức là hợp lệ) JSON. Hơn nữa, bất kỳ lỗi nào do phương pháp chuẩn vẫn dẫn đến kết quả đầu ra HTML.
Đây là nơi mà phần mềm trung gian xử lý lỗi của Express xuất hiện. Là một phần của lộ trình của tôi, tôi xác định:
app.use(function(err, req, res, next) {
console.log('Someone tried to throw an error response');
});
Tôi cũng phân lớp Lỗi thành một lớp JSONError tùy chỉnh:
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;
Bây giờ, khi tôi muốn đưa ra một Lỗi trong mã, tôi thực hiện:
var err = new JSONError(404, 'Uh oh! Can't find something');
next(err);
Quay lại phần mềm trung gian xử lý lỗi tùy chỉnh, tôi sửa đổi nó thành:
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);
}
}
Lỗi phân lớp thành JSONError rất quan trọng, vì tôi nghi ngờ rằng Express thực hiện instanceof Error
kiểm tra tham số đầu tiên được truyền cho a next()
để xác định xem trình xử lý bình thường hay trình xử lý lỗi phải được gọi. Tôi có thể xóa instanceof JSONError
kiểm tra và thực hiện các sửa đổi nhỏ để đảm bảo các lỗi không mong muốn (chẳng hạn như sự cố) cũng trả về phản hồi JSON.