Обработка ошибок по запросу
Я написал простой прокси на nodejs, и он выглядит как
var request = require( 'request' );
app.all( '/proxy/*', function( req, res ){
req.pipe( request({
url: config.backendUrl + req.params[0],
qs: req.query,
method: req.method
})).pipe( res );
});
Он отлично работает, если доступен удаленный хост, но если удаленный хост недоступен, весь сервер node выходит из строя с необработанным исключением
stream.js:94
throw er; // Unhandled stream error in pipe.
^
Error: connect ECONNREFUSED
at errnoException (net.js:901:11)
at Object.afterConnect [as oncomplete] (net.js:892:19)
Как я могу обрабатывать такие ошибки?
Ответы
Ответ 1
Глядя на документы (https://github.com/mikeal/request), вы сможете сделать что-то в следующих строках:
Вы можете использовать необязательный аргумент обратного вызова по запросу, например:
app.all( '/proxy/*', function( req, res ){
req.pipe( request({
url: config.backendUrl + req.params[0],
qs: req.query,
method: req.method
}, function(error, response, body){
if (error.code === 'ECONNREFUSED'){
console.error('Refused connection');
} else {
throw error;
}
})).pipe( res );
});
В качестве альтернативы вы можете поймать неперехваченное исключение с чем-то вроде следующего:
process.on('uncaughtException', function(err){
console.error('uncaughtException: ' + err.message);
console.error(err.stack);
process.exit(1); // exit with error
});
Ответ 2
Если вы поймаете неперехваченное исключение для ECONNREFUSED, обязательно перезапустите свой процесс. Я видел в тестировании, что сокет становится нестабильным, если вы игнорируете исключение и просто пытаетесь повторно подключиться.
Вот отличный обзор: http://shapeshed.com/uncaught-exceptions-in-node/
В результате я использовал инструмент "forever" для перезапуска моего процесса node со следующим кодом:
process.on('uncaughtException', function(err){
//Is this our connection refused exception?
if( err.message.indexOf("ECONNREFUSED") > -1 )
{
//Safer to shut down instead of ignoring
//See: http://shapeshed.com/uncaught-exceptions-in-node/
console.error("Waiting for CLI connection to come up. Restarting in 2 second...");
setTimeout(shutdownProcess, 2000);
}
else
{
//This is some other exception..
console.error('uncaughtException: ' + err.message);
console.error(err.stack);
shutdownProcess();
}
});
//Desc: Restarts the process. Since forever is managing this process it safe to shut down
// it will be restarted. If we ignore exceptions it could lead to unstable behavior.
// Exit and let the forever utility restart everything
function shutdownProcess()
{
process.exit(1); //exit with error
}