【问题标题】:Stopping response if document isn't found如果未找到文档,则停止响应
【发布时间】:2016-11-27 22:59:14
【问题描述】:

我的脚本检查数据库中是否存在 id。如果没有,它应该立即停止逻辑。

但是当前发生的不是返回“提供的项目 ID 在我们的数据库中不存在。”,而是返回“请发送所有必需的详细信息。”。 (可能是因为第一次返回把我们带出了函数)

var projectExists = function(pId, callback) {
    ProjectsData.count( {project_id: pId}, function(err, doc) {

        if (err) {
            throw err;
        }
        callback(doc);
    });
};

// Create a new Game ID.
v1.post("/", function(req, res, next) {

    if ( !("project_id" in req.body) ) {
        return res.send("You need to provide Project ID");
    }

    // Check if the Project ID is in the file.
    // Problematic bit
    projectExists( req.body.project_id, function(c) {
        if ( c == 0 ) {
            return res.send("The provided Project Id does not exist in our database.");
        }
    });

    var gameDataObj = req.body;

    GameData.addGameId(gameDataObj, function (err, doc) {
        if (err) {
            if (err.name == "ValidationError") {
                return res.send("Please send all the required details.");
            }
            throw err;
        };

        res.json(doc);
    })
});

我做错了什么?有没有更好的方法呢?


还有一个后续问题;在当前迭代中,如果 id 错误,也会出现这个错误:

Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
    at ServerResponse.header (G:\node\vnlytics\node_modules\express\lib\response.js:719:10)
    at ServerResponse.send (G:\node\vnlytics\node_modules\express\lib\response.js:164:12)
    at G:\node\vnlytics\controllers\v1\game.data.js:35:17
    at G:\node\vnlytics\controllers\v1\game.data.js:20:9
    at Query.<anonymous> (G:\node\vnlytics\node_modules\mongoose\lib\model.js:3331:16)
    at G:\node\vnlytics\node_modules\kareem\index.js:259:21
    at G:\node\vnlytics\node_modules\kareem\index.js:127:16
    at nextTickCallbackWith0Args (node.js:420:9)
    at process._tickCallback (node.js:349:13)

这可能是因为我们发送了两个响应,但奇怪的是检查 res.headersSent 直到最后一刻返回 false。

【问题讨论】:

  • 您需要对异步操作进行排序。在进行下一个异步操作之前,您无需等待第一个异步操作完成。因此,它们最终都会并行运行,当它们都完成时,您最终会尝试发送多个响应(因此会出现错误)。
  • 好的。我查了一下,似乎我也可以使用 Promise 来做到这一点,对吧?
  • 通常这意味着错误没有得到正确处理。您是否尝试过使用 next(err) 而不是 throw err 并检查错误处理程序到底发生了什么?

标签: node.js express


【解决方案1】:

正如我在评论中所说,您需要正确排序异步操作,以便在知道前一个操作的结果并处理完之前不要开始下一个操作。你可以这样做:

// Create a new Game ID.
v1.post("/", function(req, res, next) {

    if ( !("project_id" in req.body) ) {
        return res.send("You need to provide Project ID");
    }

    // Check if the Project ID is in the file.
    // Problematic bit
    projectExists( req.body.project_id, function(c) {
        if ( c == 0 ) {
            return res.send("The provided Project Id does not exist in our database.");
        } else {
            var gameDataObj = req.body;

            GameData.addGameId(gameDataObj, function (err, doc) {
                if (err) {
                    if (err.name == "ValidationError") {
                        return res.send("Please send all the required details.");
                    }
                    throw err;
                };

                res.json(doc);
            })
        }
    });

});

附:您应该用适当的错误处理替换throw err。您需要在此处实际发送错误响应。 throw 除了在从未发送过响应时停止处理之外,不会做任何有用的事情。

【讨论】:

  • 非常感谢。我不敢相信我所要做的就是添加一个 else 块。 v_v 至少我现在知道猫鼬支持承诺。非常感谢您的帮助。
  • @DragoonHP - 郑重声明,使用 Promise 会更好。您可以获得更简洁的序列化操作代码,并且通常良好的错误处理会容易得多。
猜你喜欢
  • 1970-01-01
  • 2018-05-04
  • 2020-09-28
  • 1970-01-01
  • 1970-01-01
  • 2016-05-15
  • 2023-03-19
  • 1970-01-01
  • 2017-11-27
相关资源
最近更新 更多