【问题标题】:Wrapping thrown errors so they don't crash the node webserver (node-mongodb-native)包装抛出的错误,这样它们就不会导致节点网络服务器崩溃(node-mongodb-native)
【发布时间】:2023-03-19 00:13:02
【问题描述】:

简化代码...但基本场景是我正在使用 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]

【问题讨论】:

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


    【解决方案1】:

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

    当您需要处理错误时,最普遍的方法 [需要引用] 是将其作为回调中的第一个参数传递(正如您在 findOne() 的回调中看到的那样)。在 express 中,它是使用中间件中的第三个参数(称为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。该页面还涉及如何正确响应错误。

    【讨论】:

    • 感谢您的详细回答,我现在要试一试。但是有一个问题,为什么我的 404 和 500 错误也不会停止服务器?他们使用的是相同的“抛出”机制,不是吗?
    • 错误实际上从未抛出,只是创建了一个错误对象并传递给 next()。如果 next 出现错误,express 将中止中间件链并调用任何错误处理程序,如果错误是太糟糕了,或者选择只向它所关注的客户发送消息。
    猜你喜欢
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 2022-12-09
    • 1970-01-01
    • 1970-01-01
    • 2015-01-04
    • 2013-01-16
    相关资源
    最近更新 更多