Почему первый параметр?
Из-за асинхронного характера Node.js, шаблон первый параметр-как- ошибка стал общепризнанным в качестве соглашения для обработки ошибок Node.js в пользовательской среде . Это потому что асинхронный:
try {
setTimeout(function() {
throw 'something broke' //Some random error
}, 5)
}
catch(e) {
//Will never get caught
}
Таким образом, вместо первого аргумента обратного вызова это единственный разумный способ асинхронной передачи ошибок, а не просто их выдача.
Это приведет к тому, unhandled exception
что, в том виде, в каком оно звучит, означает, что ничего не было сделано, чтобы вывести приложение из его запутанного состояния.
Исключения, почему они существуют
Однако стоит отметить, что практически все части Node.js являются источниками событий, а создание исключения является событием низкого уровня, которое может быть обработано, как и все события:
//This won't immediately crash if connection fails
var socket = require("net").createConnection(5000);
socket.on("error", function(err) {
console.error("calm down...", err)
});
Это можно, но не следует доводить до крайности, чтобы перехватить все ошибки и создать приложение, которое будет изо всех сил стараться никогда не падать. Это ужасная идея почти во всех случаях использования, поскольку она оставляет разработчика без представления о том, что происходит в состоянии приложения, и аналогична упаковке main в try-catch.
Домены - группировка событий логически
В рамках решения этой проблемы исключений, вызывающих сбой приложений, домены позволяют разработчику использовать, например, приложение Express.js, и пытаться разумно закрывать соединения в случае катастрофического сбоя.
ES6
Вероятно, упоминается, что это снова изменится, поскольку ES6 позволяет шаблону генератора создавать асинхронные события, которые по-прежнему можно отследить с помощью блоков try / catch.
Коа (написанный TJ Holowaychuck, тем же автором Express.js) заметно делает это. Он использует yield
оператор ES6 для создания блоков, которые, хотя и выглядят почти синхронно, обрабатываются обычным узлом асинхронно:
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');
})
Этот пример был бесстыдно украден отсюда .