Правильно вернуть код 404 вместо пустого массива - PullRequest
0 голосов
/ 18 мая 2018

У меня довольно простое приложение, идея в том, что у кого-то есть уникальный код, значение которого хранится в одной коллекции монго, в другой мы храним некоторые данные, которые нам нужно вернуть, если ключ был найден в первой коллекции.

Как вы, наверное, заметили, я использую 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, который вообще вместо возврата пустого массива даст нам код ошибки с сообщением?

1 Ответ

0 голосов
/ 18 мая 2018

Не совсем понятно, о чем вы спрашиваете, но если вы хотите сделать условие ошибки из чего-то, что обычно не является ошибкой, тогда для проверки требуется оператор 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);
         }
      });
    }
  });
};

Опять же, было бы лучше использовать интерфейс обещаний вашей базы данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...