Perché primo parametro?
A causa della natura asincrona di Node.js, il modello first-parameter-as-err è diventato ben definito come convenzione per la gestione degli errori Node.js dell'utente . Questo perché asincrono:
try {
setTimeout(function() {
throw 'something broke' //Some random error
}, 5)
}
catch(e) {
//Will never get caught
}
Quindi, invece, avere il primo argomento del callback è praticamente l'unico modo sensato per passare gli errori in modo asincrono oltre a lanciarli.
unhandled exception
Ciò comporterà un risultato che, proprio nel modo in cui suona, implica che non è stato fatto nulla per far uscire l'applicazione dal suo stato confuso.
Eccezioni, perché esistono?
Vale la pena notare, tuttavia, che praticamente tutte le parti di Node.js sono emittenti di eventi e il lancio di un'eccezione è un evento di basso livello che può essere gestito come tutti gli eventi:
//This won't immediately crash if connection fails
var socket = require("net").createConnection(5000);
socket.on("error", function(err) {
console.error("calm down...", err)
});
Questo può-ma-non dovrebbe essere portato all'estremo per catturare tutti gli errori e creare un'applicazione che farà di tutto per non andare in crash. Questa è un'idea terribile in quasi tutti i casi d'uso, perché lascerà lo sviluppatore senza alcuna idea di cosa stia succedendo nello stato dell'applicazione ed è analogo al wrapping di main in try-catch.
Domini: raggruppamento logico degli eventi
Come parte della gestione di questo problema di eccezioni che fanno cadere le applicazioni, i domini consentono allo sviluppatore di prendere, ad esempio l'applicazione Express.js, e provare a chiudere le connessioni in modo ragionevole in caso di guasto catastrofico.
ES6
Probabilmente sta menzionando che questo cambierà di nuovo poiché ES6 consente al modello di generatore di creare eventi asincroni che sono ancora raggiungibili con blocchi try / catch.
Koa (scritto da TJ Holowaychuck, stesso autore originale di Express.js) lo fa chiaramente. Utilizza l' yield
istruzione ES6 per creare blocchi che, sebbene appaiano quasi sincroni, vengono gestiti nel solito modo asincrono del nodo:
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');
})
Questo esempio è stato sottratto senza vergogna da qui .