Home > Blockchain >  Catch multiple nested asynchronous function errors within a single catch block
Catch multiple nested asynchronous function errors within a single catch block

Time:09-24

The code below is an example of what may take place during development.

With the current code, the outer function may throw an error but in this case wont. However, the nested function WILL throw an error (for examples sake). Once it throws the error it cannot be caught as it is asynchronous function.

Bungie.Get('/Platform/Destiny2/Manifest/').then((ResponseText)=>{

    //Async function that WILL throw an error 
    Bungie.Get('/Platform/Destiny2/Mnifest/').then((ResponseText)=>{
        console.log('Success')
    })

}).catch((error)=>{
    
    //Catch all errors from either the main function or the nested function
    doSomethingWithError(error)
});

What I want is for the outer most function to catch all asynchronous function error's but with this code I cannot. I have tried awaiting the nested function but there may be certain circumstances where it will be quicker to not wait for the function. I also tried to include a .catch() with each nested function but this would require a .catch() for each function that would allhandle the error in the same way e.g. doSomethingWithError().

CodePudding user response:

you only needs return the inner function in the outside function. see example below:

const foo = new Promise((resolve,reject) =>{
    setTimeout(() => resolve('foo'), 1000);
});

foo.then((res)=>{
    console.log(res)
    return new Promise((resolve,reject)=>{
        setTimeout(() => reject("bar fail"), 1000);
    })
}).catch((e)=>{
  // your own logic
  console.error(e)
});

this is called promise chaining. see this post for more info https://javascript.info/promise-chaining

if you have multiple promises can do something like:

const foo1 = new Promise((resolve,reject) =>{
        setTimeout(() => resolve('foo1'), 1000);
});
const foo2 = new Promise((resolve,reject) =>{
        setTimeout(() => resolve('foo2'), 2000);
});
const foo3 = new Promise((resolve,reject) =>{
        setTimeout(() => reject('foo3'), 3000);
});
const bar = new Promise((resolve,reject) =>{
        setTimeout(() => resolve('bar'), 4000);
});

foo1
.then((res)=>{
  console.log(res)
  return foo2
})
.then((res)=>{
  console.log(res)
  return foo3 // throws the error
})
.then((res)=>{
  console.log(res)
  return bar
})
.catch((e)=>{
  // every error will be cached here
  console.error(e)
});

CodePudding user response:

I would aim to use async / await unless you have very particular reasons, since it avoids callback hell and makes your code simpler and more bug free.

try {
  const response1 = await Bungie.Get('/Platform/Destiny2/Manifest/');
  const response2 = await Bungie.Get('/Platform/Destiny2/Mnifest/');
  console.log('Success');

} catch (error) {
  doSomethingWithError(error);
}

Imagine each Bungie call takes 250 milliseconds. While this is occurring, NodeJS will continue to execute other code via its event loop - eg requests from other clients. Awaiting is not the same as hanging the app.

Similarly, this type of code is used in many browser or mobile apps, and they remain responsive to the end user during I/O. I use the async await programming model in all languages these days (Javascript, Java, C#, Swift etc).

  • Related