【问题标题】:Mongoose/Typescript - UnhandledPromiseRejectionWarning when catch is presentMongoose/Typescript - 存在捕获时的 UnhandledPromiseRejectionWarning
【发布时间】:2018-05-26 19:53:30
【问题描述】:

我不确定为什么会看到这个 UnhandledPromiseRejectionWarning。在这段代码中,'id' 是一个 Mongoose 索引,我正在测试插入一个应该正确处理的重复 ID。

router.post('/create/:id', jsonParser, (req: Request, res: Response) => {
    let { id } = req.params;
    if (!req.body) {
        return res.sendStatus(400)
    }

    // @TODO add validation on JSON
    let promise = Requirement.create({id: id, data: req.body.data, deleted: false});

    promise.then((requirement) => {
        return res.json(requirement);
    });

    promise.catch((reason) => {
        let err = {'error': reason};
        return res.json(err);
    });
});

实际上返回了以下 JSON,所以我知道我的拒绝处理程序正在执行:

{
    "error": {
        "name": "MongoError",
        "message": "E11000 duplicate key error collection: rex.requirements index: id_1 dup key: { : \"REQ001\" }",
        "driver": true,
        "index": 0,
        "code": 11000,
        "errmsg": "E11000 duplicate key error collection: rex.requirements index: id_1 dup key: { : \"REQ001\" }"
    }
}

我看到的确切警告如下:

(node:11408) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: E11000 duplicate key error collection: rex.requirements index: id_1 dup key: { : "REQ001" }
(node:11408) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

【问题讨论】:

    标签: javascript typescript promise


    【解决方案1】:

    你基本上做到了

    var a = promise.then(…);
    var b = promise.catch(…);
    

    在链中创建一个分支。如果 promise 现在被拒绝,catch 回调将被调用,b 将是一个已履行的承诺,但 a 承诺也被拒绝,没有人处理。

    相反,您应该使用then 的两个参数并写入

    Requirement.create({id: id, data: req.body.data, deleted: false})
    .then(requirement => {
        res.json(requirement);
    }, reason => {
        let err = {'error': reason};
        res.json(err);
    });
    

    【讨论】:

      【解决方案2】:

      catch 捕获来自 promise 的错误,但未捕获来自 promise.then(...) 的错误。如果在then 中抛出错误,这将导致未处理的拒绝。即使它没有被抛出而是从promise 传播,它也被认为是未捕获在这个promise 中。

      应该是:

      promise
      .then((requirement) => {
          return res.json(requirement);
      })
      .catch((reason) => {
          let err = {'error': reason};
          return res.json(err);
      });
      

      【讨论】:

      • 有趣,所以在这里,promise 和 then 的异常都由 catch 处理?
      • 是的。如果它们应该单独处理,请考虑在then 之前添加另一个catch。但我想在你的情况下,它们可以用单个 catch 处理。
      猜你喜欢
      • 2018-12-06
      • 2022-06-16
      • 2018-04-01
      • 2018-03-16
      • 2017-05-05
      • 1970-01-01
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      相关资源
      最近更新 更多