Pavindu
Pavindu

Reputation: 3112

How to catch mongoose errors when updating a document

In my Node.js backend, I have an endpoint where user profile info is updated. I want to send user an error response if the new email is already in the database. However, though I have set up a try-catch in place, I still can't catch the error. Instead, the server just crashes with the following mongoose error message. I receive an error response on the front end, but after a very long time from when the error happened. All helpful advice is highly appreciated.

(node:11864) UnhandledPromiseRejectionWarning: MongoError: E11000 duplicate key error collection: testing.users index: email_1 dup key: { : "[email protected]" } ... (node:11864) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)

UpdateProfile in UserController.js

updateProfile: (id,fname,lname,email,mobile,address,next) => {
  let args = {fname,lname,email,mobile,address}        
  try{
    User.findOneAndUpdate({ "_id": id }, 
      { "$set": Utils.removeNullsFromObject(args)},
      {new: true, useFindAndModify: false}).then(function(updatedUser, err){
          if(err) {
            console.log(err);
            next(err,null)
          } else {
            next(null,updatedUser)
          }
    );
  }
  catch(err){
    console.log(err);
    next(err,null)
  }
}

Upvotes: 0

Views: 1116

Answers (1)

Vikas Keskar
Vikas Keskar

Reputation: 1248

Try...catch will work with async/await and not with promise...then. promise...then has special block called catch which can be used as,

updateProfile: (id,fname,lname,email,mobile,address,next) => {
  let args = {fname,lname,email,mobile,address}        
    User.findOneAndUpdate({ "_id": id }, 
      { "$set": Utils.removeNullsFromObject(args)},
      {
         new: true, useFindAndModify: false
    }).then(updatedUser => {
         next(null,updatedUser)
     ).catch(err =>{
       console.log(err);
       next(err,null)
    })
}

and if you want to use async/await, then,

updateProfile: async (id,fname,lname,email,mobile,address,next) => {
  let args = {fname,lname,email,mobile,address}    
    try{
     const updatedUser =  await User.findOneAndUpdate({ "_id": id }, 
      { "$set": Utils.removeNullsFromObject(args)},
      {
         new: true, useFindAndModify: false
    })
    next(null,updatedUser)
    } catch(err) {
       console.log(err);
       next(err,null)
    })
}

For more details, you can refer https://javascript.info/promise-error-handling

Upvotes: 2

Related Questions