NodeJs在异步方法中捕获未处理的错误

时间:2013-03-29 11:36:22

标签: javascript node.js error-handling

最初我想问一个关于如何基于Node.js创建robuts web服务器的问题。但是,这可能是一个非常大且含糊不清的问题。因此,我将其分解为创建robuts Web服务器时遇到的小问题和具体问题。

因此,我面临的一个挑战是如何捕获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');

那么,我是否在正确的错误处理方向上确保服务器没有停止?还是有其他机制让服务器从错误中恢复?

3 个答案:

答案 0 :(得分:4)

您需要使用domains

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

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

另外,如果您使用worker,当服务器需要关闭时,如何正常关闭它们?

你如何处理快递错误?

所有这些东西看起来都很复杂,总能保证正常关机。这就是我做node-grace的原因。

答案 1 :(得分:1)

如果使用Express是一个选项,我建议使用它而不是相当低级别的http模块。使用Express,您可以很好地处理错误:

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');

否则,请查看Node

domain模块

答案 2 :(得分: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)
 }