【问题标题】:Return 404 code in proper way instead empty array以正确的方式返回 404 代码而不是空数组
【发布时间】:2018-05-19 02:58:14
【问题描述】:

我有一个非常简单的应用程序,其想法是某人具有唯一代码,其值存储在一个 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);
      });
    }
  });
};

问题是它总是会返回数据,因为它不是抛出错误而是空数组 - 所以有没有其他好的和正确的方法,因为它应该在没有声明的情况下抛出 404 错误,例如if(length<0) res.status(404).send('Error message)。 我只是想尽量减少if 语句的数量。

也许还有其他方法可以为 mongoose 编写实现和错误处理,通常返回空数组会给我们提供带有消息的错误代码?

【问题讨论】:

  • @jfriend00 你说得对,所以我已经删除了 - 谢谢。

标签: node.js rest express mongoose


【解决方案1】:

不清楚你在问什么,但如果你想从通常不是错误的东西中产生错误条件,那么需要 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");
            }
        }
      });
    }
  });
};

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

这可能会写得更干净,并通过使用承诺接口到您的数据库合并响应并在.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 接口会更好。

【讨论】:

  • 没有 if(length 他明确提到不要使用if等声明
  • @GeorgeBailey - 我不知道有任何这种方法可以做到这一点。如果 OP 想要从通常不是错误的东西中产生错误条件,则需要 if 语句来检测该条件。
  • 是的,我也没有。如果不知道为什么 OP 想要避免这种情况,这很简单
  • @GeorgeBailey - 我在第一段中澄清了这一点。
  • 添加了一个带有实用功能的版本,可以检查数据并为您发送错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2016-10-23
  • 1970-01-01
  • 2018-07-30
  • 2021-08-17
相关资源
最近更新 更多