节点。在ES6承诺链中抛出异常

时间:2022-04-03 14:39:43

As part of an Node.js/Express API I am developing, I have built a custom error handler that lets me throw specific errors when needed e.g. BadRequest or NotFound etc.

作为节点的一部分。我正在开发的js/Express API,我已经构建了一个自定义错误处理程序,当需要时可以抛出特定的错误,如BadRequest或NotFound等。

The problem occurs when I wish to throw within a promise chain. For example:

当我想在承诺链中加入时,问题就出现了。例如:

db.doSomethingAsync().then(data => {

    if(data.length === 0){
        throw new errors.ResourceNotFound({ resource: "foo" });
    }
});

After much reading on the topic, I see that this error will be swallowed by the promise and hence causes an unhandled Promise rejection.

在阅读了很多关于这个话题的文章后,我发现这个错误会被承诺所吞噬,从而导致无法处理的拒绝承诺。

I am aware I can reject however im not sure how I can then handle the specific error (rather than a catchall on reject which I dont want).

我知道我可以拒绝,但是我不确定我如何能够处理特定的错误(而不是一个我不想要的拒绝的集合)。

Also, to reject, would I not need to create a new promise inside of my promise chain? That feels messy.

同样,要拒绝,我不需要在我的承诺链中创造一个新的承诺吗?这感觉混乱。

Can anyone advise how to handle throwing a specific exception within a promise chain?

有人能建议如何处理在承诺链中抛出一个特定的异常吗?

1 个解决方案

#1


3  

In addition to the first callback to then() which is resolve callback and recieves data, you could also provide a second callback to it which is reject callback and it recieves errors. so you could catch this specific error on the second callback of the next then:

除了第一个回调到then()即resolve callback和recieves data之外,您还可以为它提供第二个回调,即拒绝回调并接收错误。所以你可以在下一次的第二次回调中捕捉到这个特定的错误:

db
  .doSomethingAsync()
  .then(data => {
    if(data.length === 0){
        throw new errors.ResourceNotFound({ resource: "foo" });
    }
  })
  .then(massagedData => {
    // work with massagedData here
  }, err => {
    // handle err here which is previous thrown error
    // assert.ok( err instanceof errors.ResourceNotFound() )
  })
  .catch(err => {
    // this will catch unhandled errors if any
  });

then() by default returns a promise and if any of its callbacks ( whether the first or the second one ) throws an error then it returns a rejected promise and its reason will caught by next reject callback if any or by catch at the end. So you don't need to create a new promise.

然后()在默认情况下返回一个承诺,如果它的任何回调(无论是第一个还是第二个回调)抛出一个错误,那么它将返回一个被拒绝的承诺,其原因将被下一个拒绝回调捕获(如果有的话)或在最后通过catch捕获。所以你不需要做出新的承诺。

See Promise.prototype.then()

看到Promise.prototype.then()

#1


3  

In addition to the first callback to then() which is resolve callback and recieves data, you could also provide a second callback to it which is reject callback and it recieves errors. so you could catch this specific error on the second callback of the next then:

除了第一个回调到then()即resolve callback和recieves data之外,您还可以为它提供第二个回调,即拒绝回调并接收错误。所以你可以在下一次的第二次回调中捕捉到这个特定的错误:

db
  .doSomethingAsync()
  .then(data => {
    if(data.length === 0){
        throw new errors.ResourceNotFound({ resource: "foo" });
    }
  })
  .then(massagedData => {
    // work with massagedData here
  }, err => {
    // handle err here which is previous thrown error
    // assert.ok( err instanceof errors.ResourceNotFound() )
  })
  .catch(err => {
    // this will catch unhandled errors if any
  });

then() by default returns a promise and if any of its callbacks ( whether the first or the second one ) throws an error then it returns a rejected promise and its reason will caught by next reject callback if any or by catch at the end. So you don't need to create a new promise.

然后()在默认情况下返回一个承诺,如果它的任何回调(无论是第一个还是第二个回调)抛出一个错误,那么它将返回一个被拒绝的承诺,其原因将被下一个拒绝回调捕获(如果有的话)或在最后通过catch捕获。所以你不需要做出新的承诺。

See Promise.prototype.then()

看到Promise.prototype.then()