javascript - Throwing inside a catch block in a nested Promise to trigger the catch block of outer Promise, is there an alternat

I'm nesting Promises and I have to know whether the nested Promise is a rejected Promise or a fulf

I'm nesting Promises and I have to know whether the nested Promise is a rejected Promise or a fulfilled Promise to know whether to trigger the outer Promise chain's catch. To differentiate if the nested Promise is rejected or fulfilled, I use a throw in my nested Promise's catch to indicate rejection; while fulfillment is always indicated when there's no throw in my nested Promise's catch. Please take a look at the example below:

let test = new Promise((resolve, reject) => {
  resolve(42);
}).then((e) => {
  console.log(e);
  return new Promise((resolve, reject) => { //Error happens inside this nested Promise
    resolve(32);
  }).then((e) => {
    console.log(e);
    //Run other processes that may lead to an error
  }).catch((e) => { //I added this catch block for error detection, whatever error it might be
    console.log(e);
    throw(e); //I'm throwing (e) from the inner Promise's catch so that the returned Promise in the outer then is a rejected Promise, which will be "caught" by the catch block of the outer Promise
  });
}).catch((e) => {
  console.log(e); //I handle error that happen may either in the inner Promise or the outer Promise here
});

I'm nesting Promises and I have to know whether the nested Promise is a rejected Promise or a fulfilled Promise to know whether to trigger the outer Promise chain's catch. To differentiate if the nested Promise is rejected or fulfilled, I use a throw in my nested Promise's catch to indicate rejection; while fulfillment is always indicated when there's no throw in my nested Promise's catch. Please take a look at the example below:

let test = new Promise((resolve, reject) => {
  resolve(42);
}).then((e) => {
  console.log(e);
  return new Promise((resolve, reject) => { //Error happens inside this nested Promise
    resolve(32);
  }).then((e) => {
    console.log(e);
    //Run other processes that may lead to an error
  }).catch((e) => { //I added this catch block for error detection, whatever error it might be
    console.log(e);
    throw(e); //I'm throwing (e) from the inner Promise's catch so that the returned Promise in the outer then is a rejected Promise, which will be "caught" by the catch block of the outer Promise
  });
}).catch((e) => {
  console.log(e); //I handle error that happen may either in the inner Promise or the outer Promise here
});

The above shows what I meant by throw-ing inside the catch block of my nested Promise. Is the above the standard way to indicate that a nested Promise failed, or is there an alternative cleaner method to achieve what I want? As you can see, I'm practically throw-ing twice inside my nested Promise to indicate rejection. Is there a way where I can throw once and indicate Promise rejection?

EDIT

The reasons I'm using a catch block in my inner Promise and my outer Promise: I want to detect error inside my inner Promise, and said detection is done using my inner catch block; I want to handle the error that may happen in the inner Promise or in the outer Promise with the same handler, and that is done using my outer catch block. Because catch-ing inside my inner Promise returns a Promise that is considered fulfilled to my outer Promise's then block, I decided to use throw inside my inner catch block to indicate that it actually isn't fulfilled if it reached the inner catch block. I've also edited my code to indicate that the error happening inside my inner Promise is not manually triggered by me throw-ing in the code.

Share Improve this question edited May 8, 2019 at 7:49 Richard asked May 8, 2019 at 6:25 RichardRichard 7,4332 gold badges32 silver badges92 bronze badges 7
  • Why do you use catch/throw block inside nested promise? It's redundant. Use catch if you don't want your inner promise to be rejected or let your top-level promise do the job – Andrei Belokopytov Commented May 8, 2019 at 7:04
  • @AndreiBelokopytov Not always, but it's a good design to handle error in one place at any level. It depends on the scenario. Imagine that you'd like to log the error, change some state for that specific error - it's better to have it in one place (imagine the nested Promise consumed as a function from other module). – tomericco Commented May 8, 2019 at 7:13
  • @tomericco Thank you. Then in your opinion, is handling error in one place at any level and indicating a nested Promise's rejection by using a throw inside my inner Promise catch's block a good practice? – Richard Commented May 8, 2019 at 7:15
  • @tomericco I agree with you about error handling but your example does the opposite thing. You handled error in the inner promise, why do you need to throw it? If you want to handle error in the outer code then you don't need a catch block inside the inner promise. – Andrei Belokopytov Commented May 8, 2019 at 7:19
  • 1 Instead of using throw('error') you should use return Promise.reject(new Error('error')). If you use Promises you should use the Promise functions because they're made exactly for Promises and have no unexpected interactions. – Kai Lehmann Commented May 8, 2019 at 7:33
 |  Show 2 more ments

2 Answers 2

Reset to default 5

I think the clean way to do this would be using async/await. But before going there, is your question how to not run the outer promise when the inner promise fails?

The example below:

  • When the inner promise rejects, the chain stops.
  • When the outer promise rejects, the inner is already fulfilled.

const fun42 = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() =>{
            resolve(42)
            reject('something at fun 42 went wrong')
        }, 500)
    })
}

const fun32 = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() =>{
            //resolve(32)
            reject('something at fun 32 went wrong')
        }, 500)
    })
}

fun32().then(x => {
    console.log(x)
    return fun42()
}).then( y => {
    console.log(y)
}).catch (e => {
    console.log(e)
})

Well, it's a question of design. Error handling should happen in one place on each level (like you did in your example). The nested catch function handles the error the decide whether it should propagate it or quietly finish it (like your wrote).

In that specific example I would use the reject function of the wrapping Promise to reject it, other than throwing an error.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745253249a4618802.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信