Tại sao tham số đầu tiên?
Do tính chất không đồng bộ của Node.js, mẫu tham số lỗi đầu tiên đã được thiết lập tốt như một quy ước để xử lý lỗi Node.js của người dùng . Điều này là do không đồng bộ:
try {
setTimeout(function() {
throw 'something broke' //Some random error
}, 5)
}
catch(e) {
//Will never get caught
}
Vì vậy, thay vì có đối số đầu tiên của cuộc gọi lại gần như là cách hợp lý duy nhất để vượt qua các lỗi không đồng bộ ngoài việc chỉ ném chúng.
Làm như vậy sẽ dẫn đến kết quả là unhandled exception
, theo cách mà nó phát ra, ngụ ý rằng không có gì được thực hiện để đưa ứng dụng ra khỏi trạng thái bối rối của nó.
Ngoại lệ, tại sao chúng tồn tại
Tuy nhiên, điều đáng chú ý là hầu như tất cả các phần của Node.js đều là trình phát sự kiện và việc ném ngoại lệ là một sự kiện cấp thấp có thể được xử lý như tất cả các sự kiện:
//This won't immediately crash if connection fails
var socket = require("net").createConnection(5000);
socket.on("error", function(err) {
console.error("calm down...", err)
});
Điều này có thể nhưng không nên được đưa đến mức cực đoan để bắt tất cả các lỗi và tạo một ứng dụng sẽ rất cố gắng để không bao giờ gặp sự cố. Đây là một ý tưởng tồi tệ trong gần như mọi trường hợp sử dụng, bởi vì nó sẽ khiến nhà phát triển không có ý tưởng gì về những gì đang diễn ra trong trạng thái ứng dụng và tương tự như gói chính trong thử bắt.
Tên miền - nhóm sự kiện hợp lý
Là một phần trong việc xử lý vấn đề ngoại lệ này khiến các ứng dụng bị đổ, các miền cho phép nhà phát triển lấy, ví dụ như ứng dụng Express.js và thử và tắt các kết nối một cách hợp lý trong trường hợp thất bại thảm hại.
ES6
Có thể đề cập rằng điều này sẽ thay đổi một lần nữa vì ES6 cho phép mẫu máy phát tạo các sự kiện không đồng bộ vẫn có thể bắt được với các khối thử / bắt.
Koa (được viết bởi TJ Holowaychuck, cùng tác giả ban đầu của Express.js) đáng chú ý thực hiện điều này. Nó sử dụng yield
câu lệnh ES6 để tạo các khối, trong khi xuất hiện gần như đồng bộ hóa, được xử lý theo kiểu không đồng bộ nút thông thường:
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');
})
Ví dụ này đã bị đánh cắp một cách đáng xấu hổ từ đây .