包装抛出的错误,以便它们不会崩溃节点webserver(node-mongodb-native)

时间:2013-06-09 20:28:36

标签: node.js exception-handling error-handling node-mongodb-native

简化代码......但基本情况是我正在使用Mongo查找用户的findOne查询,但如果用户不存在,则会抛出错误导致整个网络服务器崩溃。有人能指出我正确的方向来正确包装这些错误,这样他们就不会把一切都搞砸了吗?

路线:

server.get('/v1/user/:token', function(req,res){
    console.log("user endpoint hit");
    var user = users.findOne({token:req.params.token}, function(err,user){
        if (user) {
            res.json({token:user.token,credits:user.credits,subscribed:user.subscribed,searches:user.searches});
        } else {
            console.log("DB error in lookup user");
            throw new DBError("Error looking up user in get endpoint");
        }
    });
});

DBError声明:

function DBError(msg) {
    this.name = "DBError";
    console.log("DBError " + msg);
    Error.call(this,msg);
    Error.captureStackTrace(this, arguments.callee);
}

这是处理错误的块:

server.error(function(err, req, res, next){
    if (err instanceof NotFound) {
        res.send(404,{error: "404 Not Found"});
    }
    else if (err instanceof DBError) {
        res.send(400, {error: "Database error"});
    } else {
        res.send(500,{error:"500 internal error"});
    }
});

现在,当我运行我的单元测试时,这是堆栈跟踪,然后结束服务器进程(不理想!):

user endpoint hit
DB error in lookup user
DBError Error looking up user in get endpoint

/Users/msencenb/Development/nodeProjects/reversePhoneLookup/server/app/node_modules/mongodb/lib/mongodb/connection/server.js:563
        throw err;
              ^
[object Object]

1 个答案:

答案 0 :(得分:1)

一般来说,你不会抛出错误。当出现严重错误时,错误应该会关闭进程/工作人员。我不会认为在上面的代码中没有找到一个非常错误的用户,但是根据你的特定情况确定这可能是不应该发生的事情。

当你需要处理错误时,[引用需要]最普遍的方式是将它作为回调中的第一个参数传递(正如你在findOne()的回调中看到的那样)。在表达中,它使用中间件中的第三个参数(称为next)和错误处理程序完成。例如:

您的路线:

server.get('/v1/user/:token', function(req,res,next){
    console.log("user endpoint hit");
    var user = users.findOne({token:req.params.token}, function(err,user){
        if (user) {
            res.json({token:user.token,credits:user.credits,subscribed:user.subscribed,searches:user.searches});
        } else {
            next(new DBError("Error looking up user in get endpoint"));
        }
    });
});

指定使用中间件的error handler

app.use(function(err, req, res, next){
  // This will handle all errors sent through next()
  console.error(err.stack);
  res.send(500, 'Something broke!');
});

另外,您可能希望查看节点中的domains。该页面还涉及如何正确回应错误。