Por que o primeiro parâmetro?
Devido à natureza assíncrona do Node.js, o primeiro-parâmetro-as-err padrão tornou-se bem estabelecida como uma convenção para o tratamento de erros userland Node.js . Isso ocorre porque assíncrono:
try {
setTimeout(function() {
throw 'something broke' //Some random error
}, 5)
}
catch(e) {
//Will never get caught
}
Portanto, ter o primeiro argumento do retorno de chamada é a única maneira sensata de passar erros de forma assíncrona, além de apenas lançá-los.
Fazer isso resultará em um unhandled exception
que, exatamente da maneira que parece, implica que nada foi feito para tirar o aplicativo de seu estado confuso.
Exceções, por que elas existem
Vale ressaltar, no entanto, que praticamente todas as partes do Node.js são emissoras de eventos e o lançamento de uma exceção é um evento de baixo nível que pode ser tratado como todos os eventos:
//This won't immediately crash if connection fails
var socket = require("net").createConnection(5000);
socket.on("error", function(err) {
console.error("calm down...", err)
});
Isso pode, mas não deve ser levado ao extremo para detectar todos os erros e criar um aplicativo que se esforçará muito para nunca travar. Essa é uma péssima idéia em quase todos os casos de uso, porque deixará o desenvolvedor sem nenhuma idéia do que está acontecendo no estado do aplicativo e é análogo ao agrupamento principal no try-catch.
Domínios - agrupando eventos logicamente
Como parte do problema com exceções que fazem os aplicativos caírem, os domínios permitem que o desenvolvedor pegue, por exemplo, o aplicativo Express.js, e tente encerrar as conexões de maneira sensata em caso de falha catastrófica.
ES6
Provavelmente, está mencionando que isso mudará novamente, pois o ES6 permite que o padrão do gerador crie eventos assíncronos que ainda podem ser capturados com blocos try / catch.
Koa (escrito por TJ Holowaychuck, mesmo autor original do Express.js) faz isso notavelmente. Ele usa a yield
instrução ES6 para criar blocos que, embora pareçam quase síncronos, são tratados da maneira assíncrona do nó usual:
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');
})
Este exemplo foi descaradamente roubado daqui .