Home > Net >  Rejection because of unhandled promise in Node Js
Rejection because of unhandled promise in Node Js

Time:11-05

Hope you are all doing fine! I am running with some difficulties when I want to deploy this api. I keep on receiving the message:"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" My guess is that I am sending a response twice, but I cannot determine where. Does anyone know what could be going on?

`

router.post('/add',async(req,res)=>{
  const friend= await User.findOne({username:req.body.friend})
  const user=await User.findById(req.body.id)

  if(friend&&friend!=req.headers.username){

    user.friends.find((x)=>{
      
      switch(friend.username){
        case user.username:{
          res.status(401).json({
            status: "Failed",
            message: "We are sorry but you cant add yourself as friend",
            data:null
        
        })
        }
        case x.friend_username:{
          res.status(401).json({
            status: "Error",
            message: `Sorry, your friend has been already added`,
            data: []
          })
        }
        default:{

          User.findByIdAndUpdate(req.body.id,{
          
            $addToSet:{friends:{
              friend_id:friend.id,
              friend_username:friend.username
            }}
              },{upsert:true,safe:true})
              
                .then(result=>{
                  res.status(200).json({
                    status: "Success",
                    message: `Friend has been added correctly! `,
                    data: result
                      })
                })
                
              .catch((err)=>{
                res.status(500).json({
                  status: "Failed",
                  message: "Database Error",
                  data: err
                 })
                })
            }
             }  }
             )}
            

     

        
     
  

   else{
  res.status(404).json({
      status: "Failed",
      message: "We are sorry but the username was not found",
      data:null
  })
  console.log(`There has been an failed attempt of adding a new user. \nUser: ${req.headers.username} `)

}
  
})

`

CodePudding user response:

Try catch block might help with debugging. And it must be used with async/await to catch unhandled promises. I am assuming that the problem is somewhere within User.findOne() or User.findById(). Ether they are working incorrectly, ether you're passing data in request incorrectly.

router.post('/add', async(req,res)=>{
  try {
        const friend = await User.findOne({username:req.body.friend})
        const user = await User.findById(req.body.id)

        if(friend&&friend!=req.headers.username){

          user.friends.find((x)=>{

            switch(friend.username){
              case user.username:{
                res.status(401).json({
                  status: "Failed",
                  message: "We are sorry but you cant add yourself as friend",
                  data:null

              })
              }
              case x.friend_username:{
                res.status(401).json({
                  status: "Error",
                  message: `Sorry, your friend has been already added`,
                  data: []
                })
              }
              default:{

                User.findByIdAndUpdate(req.body.id,{

                  $addToSet:{friends:{
                    friend_id:friend.id,
                    friend_username:friend.username
                  }}
                    },{upsert:true,safe:true})

                      .then(result=>{
                        res.status(200).json({
                          status: "Success",
                          message: `Friend has been added correctly! `,
                          data: result
                            })
                      })

                    .catch((err)=>{
                      res.status(500).json({
                        status: "Failed",
                        message: "Database Error",
                        data: err
                       })
                      })
                  }
                   }  }
                   )}
         else{
        res.status(404).json({
            status: "Failed",
            message: "We are sorry but the username was not found",
            data:null
        })
        console.log(`There has been an failed attempt of adding a new user. \nUser: ${req.headers.username} `)

      }
      } catch(err) {
      console.log(err);
      }

})

CodePudding user response:

The combination of find() and switch without breaks is probably at the cause, and certainly scrambles the logic.

There are a few other things in the code that can be improved, also. Here's an edit with the changes described in comments...

router.post('/add',async(req,res)=>{
  // surround the async calls with try/catch
  try {
    const friend = await User.findOne({ username:req.body.friend });
    const user = await User.findById(req.body.id);

    // detect and throw app-level errors. do the express response in the catch
    // get the most basic out of the way first. we need a user and a friend for the rest of the route to work
    if (!user || !friend) {
      throw {
        status: 404,
        json: {
          status: "Failed",
          message: "username or friend id not found",
          data: null
        } 
      }
    }

    // user adding themself as a friend doesn't need a loop to check
    if (friend.username === user.username) {
      throw {
        status: 401,
        json: {
          status: "Failed",
          message: "We are sorry but you cant add yourself as friend",
          data:null
        }
      }
    }

    // the loop that's needed here is hidden in includes()
    if (user.friends.includes(friend.username)) {
      throw {
        status: 401,
        json: {
          status: "Error",
          message: `Sorry, your friend has been already added`,
          data:null
        }
      }
    }
    // now, all of the errors have been detected and thrown
    // do the upsert with another await and send good status
    const addToSet = {
      $addToSet:{friends:{
        friend_id:friend.id,
        friend_username:friend.username
      }}
    };
    // note we await here (not then) since that's the style chosen above
    const result = await User.findByIdAndUpdate(req.body.id, addToSet,{ upsert:true, safe:true });
    res.status(200).json({
      status: "Success",
      message: `Friend has been added correctly! `,
      data: result
    });
  
  } catch (error) {
    console.log(error);
    res.status(error.status).json(error.json);
  }
}
  • Related