2013-03-29 49 views
0

本来我想问一个关于如何创建基于Node.js的robuts web服务器的问题。但是,这可能是一个非常大而模糊的问题。所以我将它分解为创建robuts Web服务器时所面临的小而具体的问题或挑战。NodeJs在异步方法中发生未处理的错误

因此,我面临的挑战之一是如何捕获Node.js中所有未处理的错误?我想这样做,因为我不希望任何未处理的错误停止运行Node.js,从而导致Web服务器停机。

想到的解决方案是将服务器运行代码块放在try-catch块中以捕获所有未处理的错误。但是,如果从异步方法发生任何错误,则这不起作用。例如我的Web服务器可能看起来像下面的代码:

var fs = require('fs'); 
var http = require('http'); 

try { 

    // Here is my main web server, it could happen errors by adding 
    // more and more modules and functionalities to my server. 
    // I need to catch all unhandled errors to prevent server from crashing 
    // So, I put my whole server running in a try-catch block, but any error from 
    // an async method could not be caught! 
    http.createServer(function(req, res) { 
     throw Error("An unhandled error happens!"); 
    }).listen(1234); 

}catch (e){ 
    console.log("An unhandled error caught!") 
} 

console.log('Server is listening to port 1234'); 

所以,我是在错误的处理,以确保服务器没有停止的正确方向?还是有其他一些机制可以让服务器从错误中恢复?

回答

1

如果使用Express是您的一个选择,我会建议使用该模块而不是低级http模块。随着快递,可以很好地处理错误:

var express = require('express'); 
var app  = express(); 

app.get('/', function(req, res) { 
    throw Error("An unhandled error happens!"); 
}); 

app.use(function(err, req, res, next) { 
    console.log('error', err); 
    res.send(500); // send a proper HTTP 500 message back to the client 
}); 

app.listen(1234); 

console.log('Server is listening to port 1234'); 

否则,看一看在domain模块节点

+0

感谢您的回答,我会尝试 – Shuping

+0

我不得不说我的示例只处理HTTP流内发生的错误(如路由处理程序和中间件)。在流程之外发生的任何错误(如Gabriel所称的'全球域名')不会被捕获,并且仍然需要您处理它们(最好使用Gabriels答案中描述的域名)。 – robertklep

1

使用try/catch语句内的回调函数:

var fs = require('fs'); 
var http = require('http'); 

try { 
    http.createServer(function(req, res) { 
     try{ 
      // some code trowing erors 
     }catch(e){ 
      console.log("error: " + e); 
     } 
}).listen(1234); 

}catch (e){ 
    console.log("An unhandled error caught!") 
} 

console.log('Server is listening to port 1234'); 

为什么发生?异步http回调不会像设置http服务器回调函数的代码那样运行(此外,每次服务器获取请求时都会调用该函数)。试试你的自我:

try{ 
     throw Error("An unhandled error happens!"); 
}catch(e){ 
    console.log(e) 
} 

和:

try{ 
    process.nextTick(function(){ 
     throw Error("An unhandled error happens!") 
    }); 
} 
catch(e){ 
    console.log(e) 
} 
+0

我的所有代码都变成了那些无限的尝试。在C#中,我可以捕获更高的方法中的所有错误。 Node中不可能吗? – Toolkit

+0

是的,现在可以使用[Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)和/或[async/await](https: //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) - 两者都允许代码看起来更线性 –

+0

我试过了,如果异步方法抛出错误不会冒泡 – Toolkit

4

您需要使用domains

一个全局域,每个请求包装所有服务器和一个域。如果在初始化过程中出现错误,全局域将捕获错误,那么您可以记录它,执行一些清理任务并终止服务器。如果您从请求日志中得到错误,请以最高优先级记录它,并继续处理其他请求。这就是node.js希望我们编写健壮的Web服务器的方式。

主要问题是尝试关闭尽可能优雅。一个优雅的退出意味着,当你需要杀死服务器(从ctrl-c或sigint或错误或其他)而不是做一个简单的process.exit(1)你必须清理资源,如关闭数据库连接,关闭文件,通知某人等。不能使用process.on("exit", ...),因为当调用处理程序时,事件循环不起作用,并且不能执行异步任务。

此外,如果您使用工作者,当服务器需要关闭时,如何优雅地关闭它们?

你如何处理快递错误?

所有这些东西看起来相当复杂,实现始终保证正常关机。这就是为什么我做了node-grace

+0

域稳定性:0 - 弃用 – Toolkit

相关问题