Search code examples
node.jsexpressredisazure-redis-cache

unhandled catch error in promise that has catch - Nodejs


I have a function that GETs data from either mongodb or azure redis cache. I'm trying to set it up where it checks the cache first and then hits mongodb if cache is empty, but for some reason it's executing the mongodb code first. I created a promise to handle the order, but it's giving me an unhandled promise rejection error. I have a catch so I don't understand what the issue is. I appreciate any help!

console output


SETTING TRUE...
(node:27068) UnhandledPromiseRejectionWarning: Cache found
(node:27068) 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(). (rejection id: 1)
(node:27068) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero
exit code.

GET request



  const promise = new Promise((resolve, reject) => {
      client.get("directory", (err, reply) => {
        if (reply !== null) {
          console.log("SETTING TRUE...");
          redisReply = true;

          replyConverted = JSON.parse(reply);

          res.status(200).json({
            message: "Directory retrieved successfully!",
            posts: replyConverted,
            maxPosts: replyConverted
          });
          reject("Cache found);
        } else {
          resolve();
        }
      });
    }).then(res => {
      const postPerPage = 20;
      console.log("directory ID SECTION");

      var searchKey = new RegExp(req.query.keyword, "i");

      console.log("req.query.currentPage");
      console.log(req.query.currentPage);
      console.log(req.query.keyword);
      let currentPage = req.query.currentPage;

      console.log("REDIS RELY IS " + redisReply);
      console.log("GRABBING FROM COSMOSDB");
      User.countDocuments({
        $and: [{ username: searchKey }, { role: "Seller" }]
      })
        .then(docs => {
          console.log("COUNT");
          console.log(docs);
          let totalPosts = docs;
          User.find({
            $and: [{ username: searchKey }, { role: "Seller" }]
          })
            .select("_id username")
            .skip(postPerPage * (currentPage - 1))
            .limit(postPerPage)
            .then(documents => {
              res.status(200).json({
                message: "Directory retrieved successfully!",
                posts: documents,
                maxPosts: totalPosts
              });

              let docsString = JSON.stringify(docs);
              client.set("directory", docsString, (err, reply) => {
                console.log(reply);
              });
            });
        })
        .catch(err => {
          console.log("Skipped Mongodb");
        });


Solution

  • You can make a function to first search the cache if found use it if not make query and then take callback with the result. In your case it might look something like this also you might want to make the key dynamic to correspond with your query

    module.exports.findDirectory = function(client,query, callback){
        client.get(query, (err, reply) => {
         if (err) {
           callback(null);
        } else if(reply){
    
        callback(JSON.parse(reply));
    
        } else {
        User.countDocuments({
                $and: [{ username: query.searchKey }, { role: "Seller" }]
              })
                .then(docs => {
                  console.log("COUNT");
                  console.log(docs);
                  let totalPosts = docs;
                  let postsPerPage = 9;
                  User.find({
                    $and: [{ username: query.searchKey }, { role: "Seller" }]
                  })
                    .select("_id username")
                    .skip(postPerPage * (query.currentPage - 1))
                    .limit(postPerPage)
                    .then(documents => {
    
    
             let docsString = JSON.stringify(docs);
             client.set(query, docsString, (err, reply) => {
                        console.log(reply);
                        callback(docs)
               });
           });
        }
    
      })
    
    }
    

    then use it in the route like this

    dirsController.findDirectory(client,req.query,function(dirs){
    
       res.send(dirs)
    }