What is the correct way of writing endpoint functions for Mongoose with Express?

Viewed 86

Writing the backend API for my app I've encountered countless examples of people using both forms of handling errors in their endpoint functions, as presented below:

Option 1:

 export const deleteProject = asyncHandler(async(req, res) => {
        const project = await Project.findByIdAndDelete(req.params.id);

        if(project) {
            res.status(204).send();
        } else {
            res.status(404).json({message: "Project not found"});
            throw new Error('Project not found');
        }
});

Option 2:

 export const deleteBoard = asyncHandler(async(req, res) => {
        try {
            await Board.findByIdAndDelete(req.params.id);
            res.status(204).send();
        } catch(err) {
            res.status(404).json({message: "Board not found"});
            throw new Error('Board not found');
        }
});

To my current understanding, both of those are correct. I wanted to ask - is one of them preferable because of reasons I might not be aware of?

3 Answers

I prefer option number #2.

Remember findByIdAndDelete can give n types of error so. you need to change your code like this.

export const deleteBoard = asyncHandler(async(req, res, next) => {
    try {
        const board = await Board.findByIdAndDelete(req.params.id);
        if(board)
          return res.status(204).send();
        res.status(404).json({message: "Board not found"});
    } catch(err) {
       // don't throw anything here 
       // throw new Error('Board not found');
       // use next(errmsg) which will call global error handler
       next(err);
    }

Since you don't need the item after delete, you can use a better function deleteOne or deleteMany.


  const deleted = await Board.deleteOne({ _id: req.params.id }).exec();
  if (deleted.deletedCount) 
      return res.status(204).send();
  res.status(404).json({message: "Board not found"});

The try-catch statement should be executed only on sections of code where you suspect errors might occur, and due to the overwhelming number of possible circumstances, you cannot completely verify if an error will take place, or when it will do so. In the latter case(Option 2), it is presented appropriately to use try-catch.

for mongoose query use then block at the end of api and you can easily handle it like

await table.findByIdAndDelete({...})
.then(obj => {
   return res.status()//check on the response from query basis
})
.catch(err => {
   res.status(401).send({msg: "Error in db"})
})

Reason

by using then block your axios wait until he did't get a response from api and by using then and catch block the api don't send any response until query is not executed. In your option-1 what you do if mongoose in is running and Node send the response before query execution as node is a single threaded.

Related