Home > Blockchain >  Try/catch async function outside of async context
Try/catch async function outside of async context

Time:07-11

I have a few classes which use 'dns' from node.js. But when an error occurs, my app is thrown. I made a siimple example with classes and throwable functions and I faced with the same problem. It's works if an exception is thrown from function but it doesn't work if an exception is thorwn from class. Example:

class Test {
  constructor() {
    this.t();
  }
  async t() {
    throw new Error("From class");
  }
}

async function test(){
  new Test();
}

try {
  test().catch(e => {
    console.log("From async catch");
  });
} catch (e) {
  console.log("From try catch");
}

Output:

Uncaught (in promise) Error: From class
    at Test.t (<anonymous>:6:11)
    at new Test (<anonymous>:3:10)
    at test (<anonymous>:11:3)
    at <anonymous>:15:3

How to catch errors from try/catch block in this example?

CodePudding user response:

You generate multiple async-requests but you can only catch errors from the first one:

  1. You create a promise with async function test().

  2. Then you create a syncronous call within it, with new Test(), every error syncronously thrown from within it will be catched by the catch.

  3. Then you generate another promise call from within the syncronous constructor, this error can't be caught by the try/catch-block or .catch at, or above the async function test().

    It is similar to this:

    constructor() {
      new Promise(() => throw new Error(''))
    }
    

So you have 3 possible ways to solve it:

  1. You catch the error inside the async t() {}-call.
  2. You catch it inside the constructor with this.t().catch(console.error) (which can't be forwarded to the try/catch block) as it is forwarded to the catch block of the Promise behind the async call. And if there is no .catch on the async call, you get the "Unhandled Promise rejection"-Error.
  3. Don't call the async function from within the constructor at all, use it like this:
    class Test {
      async t() {
        throw new Error("From class");
      }
    }
    
    async function test(){
      await (new Test()).t();
    }
    
    try {
      test().catch(e => {
      console.log("From async catch");
     });
    } catch (e) {
      console.log("From try catch");
    }
    

CodePudding user response:

Don't make async methods)))

Your solution looks somewhat like this.

class Test {
  constructor() {
    this.t();
  }
  t() {
    (async () => {
      try {
        throw new Error("From class");
      } catch (e) {
        console.log(e);
      }
    })();
  }
}

Have a nice rest of your day

  • Related