Dlaczego pierwszy parametr?
Ze względu na asynchroniczną naturę node.js The pierwszy parametr-as-err wzór stał się uznanym konwencji dla obsługi błędów userland node.js . Dzieje się tak, ponieważ asynchroniczne:
try {
setTimeout(function() {
throw 'something broke' //Some random error
}, 5)
}
catch(e) {
//Will never get caught
}
Więc zamiast tego posiadanie pierwszego argumentu wywołania zwrotnego jest właściwie jedynym rozsądnym sposobem na asynchroniczne przekazywanie błędów, inny niż tylko ich zgłaszanie.
Spowoduje to unhandled exception
, że w wyniku tego, tak jak to brzmi, nie zrobiono nic, aby wyprowadzić aplikację ze stanu pomieszania.
Wyjątki, dlaczego one istnieją
Warto jednak zauważyć, że praktycznie cała część Node.js to emitery zdarzeń, a zgłoszenie wyjątku jest zdarzeniem niskiego poziomu, które można obsłużyć jak wszystkie zdarzenia:
//This won't immediately crash if connection fails
var socket = require("net").createConnection(5000);
socket.on("error", function(err) {
console.error("calm down...", err)
});
To może, ale nie powinno być doprowadzane do skrajności, aby wyłapać wszystkie błędy i stworzyć aplikację, która będzie bardzo się starała, aby nigdy się nie zawiesić. Jest to okropny pomysł w prawie każdym przypadku użycia, ponieważ pozostawi programistę bez pojęcia, co się dzieje w stanie aplikacji i jest analogiczne do pakowania main w try-catch.
Domeny - logiczne grupowanie zdarzeń
W ramach rozwiązywania problemu wyjątków powodujących przewracanie się aplikacji, domeny pozwalają deweloperowi wziąć na przykład aplikację Express.js i spróbować rozsądnie zamknąć połączenia w przypadku katastrofalnej awarii.
ES6
Prawdopodobnie wspomina, że to się zmieni ponownie, ponieważ ES6 umożliwia wzorcowi generatora tworzenie zdarzeń asynchronicznych, które są nadal możliwe do złapania za pomocą bloków try / catch.
Koa (napisany przez TJ Holowaychucka, tego samego oryginalnego autora Express.js) wyraźnie to robi. Używa instrukcji ES6 yield
do tworzenia bloków, które wyglądają prawie synchronicznie, ale są obsługiwane w zwykły sposób asynchroniczny węzła:
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');
})
Ten przykład został stąd bezwstydnie skradziony .