Проблема с экспресс-маршрутизацией сервера

#javascript #node.js #mongodb #express

#javascript #node.js #mongodb #экспресс

Вопрос:

Я пытаюсь добавить новый маршрут для получения пользователя по идентификатору, но моя обработка ошибок работает некорректно. Вот код для этого маршрута.

 const express = require('express');

require('./db/mongoose');
const User = require('./models/user');
const Task = require('./models/task');

const app = express();
const port = process.env.PORT || 3000;

app.use(express.json());

//  ***removed code for brevity
// Route for fetching user by id

app.get('/users/:id', (req, res) => {
    //console.log(req.params.id);
    const _id = req.params.id;

    User.findById(_id)
        .then(user => {
            //console.log(user)
            if (!user) {
                return res.status(404).send();
            }
            res.send(user);
        })
        .catch(e => {
            res.status(500).send();
        });
});
  

Итак, если я протестирую маршрут на Postman и введу правильный идентификатор пользователя из базы данных, я получу, что пользователь отправлен обратно, что является правильным ответом. Но если я ввожу неправильный идентификатор пользователя, я получаю ответ с кодом ошибки 500 вместо кода ошибки 404. Оператор if (!user) пропускается, и я не могу понять, почему. Есть мысли относительно того, чего мне не хватает?

Комментарии:

1. это означает, что у вас ошибка в User.findById том, что вы перехватываете его ошибку и отправляете статус 500 .. не могли бы вы опубликовать код и как он экспортируется? также вы могли бы console.log(e) в catch(e) блоке, и вы увидите, что это за ошибка

2. Итак, это весь пользовательский файл, который мне требуется

3. const User = new mongoose.model('User', { name: { type: String, required: true, trim: true }, email: { type: String, require: true, trim: true, lowercase: true, validate(value) { if (!validator.isEmail(value)) { throw new Error('Email is invalid'); } } }, password: { type: String, required: true, trim: true, minlength: 7, validate(value) { let pwd = value.toLowerCase().includes('password'); if (pwd) { console.log("Your password can't contain the word password."); } } // if include password },

4. Не уверен, почему это так выглядит, извините. Но я экспортирую его, вызывая module.exports = User

5. Если бы вы вошли в систему e вместо того, чтобы просто игнорировать это, вы, вероятно, узнали бы об ошибке.

Ответ №1:

Запуская это через мой личный проект, использующий mongoose / express, я получаю следующую ошибку:

  UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed for value "12345" at path "_id" for model "User"
  

Это в основном означает, что Mongoose ожидает свой собственный определенный тип объекта, «ObjectId». Это небольшая проблема, поскольку обычно, если вы используете .findOne({_id: something), вы можете просто использовать строку. Если мы сделаем:

 User.findById(mongoose.Types.ObjectId(_id))
  

это должно сработать. Обратите внимание, что если вы используете недопустимый идентификатор (как я, очевидно, сделал здесь, это все равно приведет к ошибке. По этой причине я бы использовал стандартный формат NodeJS для обратного вызова:

 .then((err,result)=>{
   //other stuff
});
  

В общем, блокировка .catch () должна выполняться только в том случае, если очевидно, что Mongoose и ваш маршрутизатор не может с этим справиться.

РЕДАКТИРОВАТЬ: Кроме того, для получения дополнительной информации, Mongoose.model.findById является встроенным удобным методом и в основном должен выполнять именно то, что указано в tin.

Комментарии:

1. Спасибо за советы.