Search code examples
node.jsmongooseerror-handlingevent-handlingmongoose-models

cannot handle model.save error and return to FE


I'm trying to save an item to DB using Mongoose and return the saved item or the error to the client. When making a postman call with a duplicate document i expect to get an error of duplicated, get to the 'catch' statement and retrieve a 500 status code and a message. However, i always get to 'then' with result undefined and status code 200. I also tried to change the 'throw' to 'return' but with no success. Where i'm wrong?

Route:

router.post("/", (req, res) => {
  const schema = Joi.object({
    // id: Joi.number().required(),
    name: Joi.string().min(3).required(),
    description: Joi.string().optional(),
    categoryID: Joi.number().required(),
    // ingredients: Joi.array().optional(),
    price: Joi.number().required(),
    vegan: Joi.boolean().required(),
    special: Joi.boolean().required(),
    img: Joi.string(),
  });
  let result = schema.validate(req.body);

  if (result.error) {
    res.status(400).send(result.error);
    return;
  }

  let menu = new Menu();
  const {
    // id,
    name,
    description,
    categoryID,
    ingredients,
    price,
    vegan,
    special,
    // img,
  } = req.body;

  // menu.id = id;
  menu.name = name;
  menu.categoryID = categoryID;
  menu.description = description;
  menu.ingredients = ingredients;
  menu.price = price;
  menu.vegan = vegan;
  menu.special = special;
  // menu.img = img;

  MenuService.saveMenuItem(menu)
    .then((result) => {
      return res.json(result);
    })
    .catch((err) => {
      return res.status(500).send(err);
    });
});

Service:

async function saveMenuItem(menuItem) {
  await menuItem.save((err, item) => {
    if (err) throw new Error(err.message);
    return item;
  });
}

module.exports.saveMenuItem = saveMenuItem;

This is the route.

This is the service.


Solution

  • you may should try this:

    async function saveMenuItem(menuItem) {
    return new Promise((resolve, reject)=>{
          menuItem.save((err, item) => {
             if (err) reject(err.message);
             resolve(item);
    })
    }