【问题标题】:How to throw an exception from a Promise to the Caller without an UnhandledPromiseRejectionWarning如何在没有 UnhandledPromiseRejectionWarning 的情况下从 Promise 向调用者抛出异常
【发布时间】:2021-03-22 04:39:56
【问题描述】:

考虑这个包含catch 块的数据库查询处理程序:

async function dml(pool, sql, expected = -1) {
  p(sql)
  let rowCnt = await pool.query(sql)
    .then(r => {
      if (expected >= 0 && r.rowCount != expected) {
        throw `DML [${sql}] had wrong number of results: ${r.rowCount} vs expected=${expected}`
      } else {
        return r.rowCount
      }
    })
    .catch(err => {
      msg = `Query [${sql}] failed: ${err}`;
      printError(msg,err)
      throw msg   // THIS is the problem. It generates UnhandledPromiseRejection
    }
  return rowCnt
}

抛出的异常打算在这里被调用者捕获:

 async function handleClip(data) {
   ..
   // calling code
   try { 
    //  ...
    let cnt = db.dmlClips(sql, 1)   // Throw() happens in this invocation
    debug(`Update count is ${cnt}`)
    return rcode
  } catch (err) {
      //   WHY is the thrown exception not caught here??
    let msg = `Error in handleClip for data=${data.slice(0,min(data.length,200))}`;
    error(msg,err);
  }

但上述结构显然不能接受:产生以下严重警告:

(node:39959) UnhandledPromiseRejectionWarning: Query [insert into clip ...] failed: error: role "myuser" does not exist
    at emitUnhandledRejectionWarning (internal/process/promises.js:170:15)
    at processPromiseRejections (internal/process/promises.js:247:11)
    at processTicksAndRejections (internal/process/task_queues.js:94:32)
(node:39959) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 
This error originated either by throwing inside of an async function without a catch block, or 
by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict`
 (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:39959) [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.
    at emitDeprecationWarning (internal/process/promises.js:180:11)
    at processPromiseRejections (internal/process/promises.js:249:13)
    at processTicksAndRejections (internal/process/task_queues.js:94:32)

那么这需要如何设置呢?注意这里有一个相关的问题:how to properly throw an error if promise is rejected? (UnhandledPromiseRejectionWarning)。但是对于那个问题,提问者没有任何异常处理程序/捕获块。

【问题讨论】:

  • 你可以使用 await 吗? >let cnt = db.dmlClips(sql, 1)。函数名称也不匹配
  • @RifatBinReza 你说得对,我需要一个 await 。请给出答案

标签: javascript node.js promise try-catch


【解决方案1】:

当您调用函数db.dmlClips(sql, 1) 时,您需要使用await,以便它等待promise 被解析/拒绝。将行改为let cnt = await db.dmlClips(sql, 1)

【讨论】:

    【解决方案2】:

    看起来您从中调用db.dmlClips 的try-catch 块不在async 函数内。在没有 async 关键字的函数中声明的 Try-catch 不会捕获 Promise 拒绝。

    【讨论】:

    • 实际上它 is 在异步中:但我忽略了该信息。正如评论者所说,我可能还需要一个 await 。我现在正在尝试
    • 我赞成,因为您关于处于异步函数中的评论是有效的
    猜你喜欢
    • 2013-01-01
    • 1970-01-01
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多