以适当的方式返回404代码而不是空数组

时间:2018-05-18 17:50:17

标签: node.js rest express mongoose

我有一个非常简单的应用程序,这个想法是有人有唯一的代码,哪个值存储在一个mongo集合中,另外我们保留了一些数据,如果在第一个集合中找到了密钥,我们需要返回这些数据。

您可能已经注意到我正在使用NodeJS和MongoDB以及Mongoose,Express。

我的方法有问题:

exports.getCompanyByKey = function(req, res) {
  console.log(req.params.keyvalue);
  var query = Company.where({keyValue : req.params.keyvalue});
  query.findOne(function(err, company){
    if(err){
      res.send(err);
    }else{
      SampleData.findOne({}, function(err, sample_data){
        if(err)
          res.send(err);
        res.json(sample_data);
      });
    }
  });
};

问题是它总会返回数据,因为它没有抛出错误而是空数组 - 所以还有其它任何正确的方法,因为它应该是没有声明而没有if(length<0) res.status(404).send('Error message)这样的语句。  我只想简化if语句的数量。

也许还有其他一些方法可以为mongoose编写实现od错误处理,一般而言返回空数组会给我们带错误的错误代码吗?

1 个答案:

答案 0 :(得分:0)

你要问的是什么并不完全清楚,但是如果你想通过一些通常不是错误的东西来制造错误条件,那么需要if语句(或其他类似的测试)测试该特定条件。

您可以创建自己的查询功能,将空响应转换为错误,如果需要,您可以“隐藏”该功能中的if条件,但它仍然是if条件,测试你的具体情况。

因此,如果数组为空,则返回404,您只需添加if语句(如您所知):

exports.getCompanyByKey = function(req, res) {
  console.log(req.params.keyvalue);
  var query = Company.where({keyValue : req.params.keyvalue});
  query.findOne(function(err, company){
    if(err){
      res.status(500).send(err);
    } else {
      SampleData.findOne({}, function(err, sample_data){
        if(err) {
          res.status(500).send(err);
        } else {
            if (sample_data.length) {
              res.json(sample_data);
            } else {
              res.status(404).send("no data");
            }
        }
      });
    }
  });
};

仅供参考,您还需要确保在出现错误时正确设置状态代码并且您永远不会向同一请求发送多个响应(即使出现错误)。我还在你的代码中解决了几个问题。

通过使用数据库的promise接口并在一个.catch()中发送错误,可能会写得更清晰,反应更新。

例如,您可以通过为.findOne()创建一个实用程序函数来简化代码,该函数会自动检测并发送错误响应:

function findOne(res, db, q, cb) {
    db.findOne(q, function(err, data) {
        if (err) {
            res.status(500).send(err);
            cb(err);
        } else if (!q.length) {
            res.status(404).send("no data");
            cb(new Error("no data"));
        } else {
            cb(null, data);
        }
    });
}

然后,您的功能可以简化为:

exports.getCompanyByKey = function(req, res) {
  var query = Company.where({keyValue : req.params.keyvalue});
  query.findOne(function(err, company){
    if(err){
      res.status(500).send(err);
    } else {
      findOne(res, SampleData, {}, function(err, sample_data) {
         // any error response has already been sent
         if (!err) {
              res.json(sample_data);
         }
      });
    }
  });
};

同样,使用你的Db的promise接口会更好。