Search code examples
javascriptasync-awaitpromiseecmascript-2016

Resolves propagating up multiple calling async functions


I've been trying to get the rejects of my asynchronous functions to bubble back up to their callers, but it's not working for some reason. Here's some tested example code:

"use strict";

class Test {
   constructor() {
      this.do1();
   }

   async do1() {
      try { this.do2(); } catch(reason) { console.error(reason); }
   }

   async do2() {
      for(let i = 0; i < 10; i++) {
         await this.do3();
         console.log(`completed ${i}`);
      }
      console.log("finished do1");
   }

   async do3() {
      return new Promise((resolve, reject) => {
         setTimeout(() => {
            if(Math.random() < 0.3) reject('###rejected');
            else resolve("###success");
         }, 1000);
      });
   }
}

export default Test;

Chrome just gives me this every time: Unhandled promise rejection ###rejected.

Any idea why this is happening? I'd like to be able to handle all thrown errors from a higher level than do2() (the above example works fine if the try/catch is in do2() and wraps await this.do3();). Thanks!

Edit: To be a bit more explicit, if I take the try/catch out of do1() and put it in do2() as follows, everything works fine:

async do2() {
   try {
      for(let i = 0; i < 10; i++) {
         await this.do3();
         console.log(`completed ${i}`);
      }
      console.log("finished do1");
   } catch(reason) { console.error(reason); }
}

Solution

  • async do1() {
        try {
            await this.do2();
        }
        catch(reason) {
            console.error(reason);
        }
    }
    

    do2 is an asynchronous function. And you call it without await. So, when it completes there's no try-catch clauses around it.

    See this question and this article for more details.