tbowden
tbowden

Reputation: 1058

How to pass errors to a parent function in node, when using mongodb

I am building a simple API that updates a record and then send a response (using MonogoDB).

It works well, however I'm trying to figure out how to best handle errors and pass them to router function, to respond with an error. I've been doing lots of reading, however can't figure something out.

In the below example a request comes to the /endpoint, then an asynchronous function is called, named, updateQuery.

There are two types of failure errors I believe I can get; 1) MongoError and 2) Errors where I have tried to update a record, however nothing has been updated - for example where I try to update a record that doesn't exist.

In the event of a MongoError - These get picked up by the catch() block in the updateQuery. My question in this case is, as this is caught by the the catch() block in the updateQuery function, how do I then pass this error to the router function, to respond with an error status code?

In the second scenario, as in the below example, I can see if when nothing has been updated using an if statement, however again I'm unsure how to pass that to the router function to issue a response. Do I use an if else statement? i.e if result == true, then proceed, else show error?

Thanks

Router Function

router.put("/endpoint", async (req, res) => {
      await updateQuery()
        .then(() => {
            res.status(200).json({ status: 201 });
        })
        .catch((err) => console.error(`Fatal error occurred: ${err}`));
    });

updateQuery Function

async function updateQuery() {
  const db = await mongoUtil.getDb();

  return await db
    .collection("test")
    .updateOne(
      {
        _id: <id>,
      },
      {
        $set: {
          param: 'test'
        },
      }
    )
    .then((result) => {
      if (result.nModified !== 1) {
        throw new Error("Update Error");
      }
    })
    .catch((err) => console.error(`Fatal error occurred: ${err}`));
}

Upvotes: 0

Views: 592

Answers (1)

user15672038
user15672038

Reputation:

  • First of all, in my opinion, it's kind of redundant to use async/await together with then/catch.
  • Secondly, you can just use the catch in the top-level function, and any errors are thrown either by you or the server will be caught.
  • Finally, express is a middleware-based framework, and the route handler can receive another argument which is 'next' which is the next handler in the chain that will also receive the request, response, and other arguments you pass to it, so for example, you can add a middleware that creates a response based on the error it received. and then you can just use something like .catch((error) => next(error)) or alternatively using the try/catch syntax.

So your final code can look something like this:

router.put("/endpoint", async (req, res, next) => {
  try {
    await updateQuery() 
    res.status(200).json({ status: 201 });
  } catch(error) {
    next(error);
  }  
});

Upvotes: 1

Related Questions