0

The below code doesn't handle error though condition is satisfied. Please help understand why

Edit:the below code now terminates code flow in case of satisfying condition but throwing a error result in unhandled rejection.

utils.js

const isMaximum = Id => {
 return db.Entries
   .findAndCountAll()
   .then(counts => {
     let numberOfEntries = 2;
     let maxEntries = 2;
       if (numberOfEntries == maxEntries) {
         return true;
       }
       else{
         return false;
       }
     });
};

xyz.js

const doSomething=(req,res,next)=>{
    Utils.isMaximum(id).then(isLimit=> {

           if(isLimit) throw new Error("not allowed"); //unhandled rejection
         //rest of code gets terminated as expected
 });
}

Related questions Why can I not throw inside a Promise.catch handler? couldn't find me a solution. So please make it clear.

Gayathri
  • 1,414
  • 3
  • 16
  • 37
  • Can you show "//rest of code"? What comes after the invocation of Utils.isMaximum? If you want to skip some parts of your promise chain, you can add a catch at the end of the chain to skip all the methods starting from where you're throwing the error up until the first catch method. – Ramtin Soltani Feb 17 '18 at 08:00
  • Uh, what do you want the exception to do? What else did you expect if not a promise rejection? How and where do you want to handle the error? – Bergi Feb 17 '18 at 11:05

2 Answers2

2

Throwing inside a .catch() handler makes the promise chain a rejected promise. If you don't have a subsequent .catch() handler, then it will get reported as an unhandled promise rejction because you have no .catch() afterwards to catch the rejected promise. This is nearly always a programming error which is why you get the warning.

Throwing inside a .catch() does not terminate your program. That exception is caught by the promise infrastructure (and turned into a rejected promise). That's how promises work (by specification). If you want your program to terminate at that point, then you can call process.exit() rather than throwing.


Now you've edited your question and now you're trying to throw inside a .then() handler. OK. I'll address what you've added. Next time please start with the whole code context so we can more quickly understand the situation.

Utils.isMaximum() is asynchronous. It returns a promise. You need to program with using asynchronous techniques. You can't think like synchronous sequential code. Any code that comes after your call to Utils.isMaximum() will execute BEFORE the .then() handler is called.

Here's a simple example:

Utils.isMaximum(id).then(isLimit => {
   console.log("A");
});
console.log("B");

That will output:

B
A

So, for starters, you can't prevent the code that comes after the .then() block from running by anything you do inside the .then() block because the rest of the function executes BEFORE the .then() handler does.

So, the usual way you deal with that is you have to put the rest of the code INSIDE the .then() handler or inside a function you call from there:

const doSomething=(req,res,next)=>{
    Utils.isMaximum(id).then(isLimit=> {
         if(!isLimit){
               // rest of code here that sends regular response
         } else {
               // handle error here - send error response
               // or OK to throw here, throw will be caught by next .catch()
         }
    }).catch(err => {
          // send error response here
    });
}
jfriend00
  • 580,699
  • 78
  • 809
  • 825
  • I need to terminate the flow with that error message as alert in frontend. So, i have to throw the error message. – Gayathri Feb 17 '18 at 07:01
  • @Gayathri - What does "terminate the flow" mean? You don't show anything else in your question so I have no idea what that means. – jfriend00 Feb 17 '18 at 07:02
  • Is there a way to just throw error message received from a promise, in general? – Gayathri Feb 17 '18 at 07:02
  • @Gayathri - What does "throw error message" mean? A `.then()` or `.catch()` handler catches any exception and turns it into a rejected promise. That's what it does. The exception is caught and handled by the promise infrastructure. It doesn't terminate your program. Use `process.exit()` if you want to terminate your program. – jfriend00 Feb 17 '18 at 07:03
  • consider isMaximum function returns reject on a condition like if a==b, return reject ("this is not allowed"). That error message need to be thrown as alert. And the next lines of method where isMaximum is called shouldn't get executed – Gayathri Feb 17 '18 at 07:06
  • @Gayathri - Show the rest of the code in that function and describe exactly what you want to have happen in that code when you encounter an error and then we help you further. There is no automatic "thrown as alert" in Javascript so I don't know what that means. I've already described to you exactly what happens in a `.catch()` handler when you throw. – jfriend00 Feb 17 '18 at 07:21
  • @Gayathri - If you're trying to do the equivalent of a synchronous `throw` from within a `.catch()` handler (which is asynchronous), you simply can't program that way. That's just not how promises work and there is no work-around that does the same as a synchronous `throw`. It wouldn't do you much good anyway because your containing function has already exited anyway because the `.catch()` handler is called later asynchronously. The name of your function `Utils.isMaximum()` makes me wonder why it's returning a promise in the first place? Why even use a promise there? – jfriend00 Feb 17 '18 at 07:28
  • @Gayathri - It appears you don't quite understand how the timing of asynchronous callbacks works. I've added a bunch more to my answer to try to explain. In any case, you can't use `throw` to do what you're trying to do. You have to program it a different way. – jfriend00 Feb 17 '18 at 08:01
  • Even doing this way gives unhandled rejection.But good part is it terminates flow – Gayathri Feb 17 '18 at 08:38
  • Thanks a lot jfriend00. You kinda opened my eyes . – Gayathri Feb 17 '18 at 09:45
  • @Gayathri - I added a `.catch()` handler so as long as you don't throw in the `.catch()` handler, there should be no unhandled rejection any more in this code. – jfriend00 Feb 17 '18 at 16:46
  • @Gayathri - If this answered your question, you can indicate that to the community here by clicking the checkmark to the left of the answer. That will also earn you some reputation points for following the proper procedure. – jfriend00 Feb 17 '18 at 16:48
  • I faced this issue all because of missing catch, like my answer below. It's good you helped me understand promise complete. – Gayathri Feb 17 '18 at 17:32
0

I didn't catch the error I throw and that is the only reason why. Below resolved.

const doSomething=(req,res,next)=>{
    Utils.isMaximum(id).then(isLimit=> {

           if(isLimit) throw new Error("not allowed"); 
 }).catch(next);
   //rest of code gets terminated as expected

}
Gayathri
  • 1,414
  • 3
  • 16
  • 37