Unhandle rejection promise async await chain

Jul*_*dez 7 node.js async-await

我在javascript中对async await相当新,所以这个问题可能是我不知道的.

我有这个

  async foo(req, res, next) {
    try {
      await scan(req.params.stack);
      res.send('ok');
    } catch (err) {
      res.status(500).send('fail');
    }
  }

async scan(stack) {
  try {
    const libs = [1,2,3];
    const promises = libs.map(async l => analyze(stack, l)
      .catch((err) => { throw new Error(err); }));
    return q.allSettled(promises)
      .then((results) => {
        const rejected = results.filter(r => r.state === 'rejected');
        if (rejected.length === results.length) throw new Error('Failed');
        return results;
      })
      .catch((err) => {
        throw new Error(err);
      });
  } catch (err) {
    throw new Error(err);
  }
}

async function analyze(stack, libraries) {
  try {
    const config = await buildConfiguration(stack, libraries);
    return await databaseInsertion(vulnsObject);
  } catch (err) {
    return Promise.reject('Error while trying to analyze libs');
  }
}
Run Code Online (Sandbox Code Playgroud)

不知怎的,我得到了这个疯狂的警告,我不知道我在哪里没有发现错误.

当然我正在使构建配置失败以便测试错误,但是没有正常的流量导致错误我得到了这个:

(node:415) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): Error: Error while trying to analyze libs
Run Code Online (Sandbox Code Playgroud)

我使用异步等待好吗?是否有任何模式我应该遵循链接异步等待?

狂野的是foo函数运行良好,这意味着res.status.(500).send('fail'); 工作,我得到了回应

当我使用正常承诺时,没有出现此错误.

我真的被困在这里

Aks*_*tap 1

调用async函数(此处为analyze)将返回一个 Promise,该 Promise 将根据async函数的返回值或是否抛出错误来解析或拒绝。

现在,该函数正在处理抛出的错误,但当抛出错误时analyze它将返回 a 。Promise.reject()这里的APromise.reject()是未处理的拒绝,这就是日志所说明的内容。

就同​​步函数而言,等价物是

function sync() {
  try {
    // do something dangerous
  } catch (ex) {
    throw Error('Something bad happened'); // this error is still being thrown and nobody is handling it
  }
}
Run Code Online (Sandbox Code Playgroud)

要处理此错误,您可以在调用sync时执行以下操作,将其包装在try中并再次捕获

try {
  sync();
} catch (ex) {
  console.error(ex); // not gonna throw another exception, otherwise the program might crash
}
Run Code Online (Sandbox Code Playgroud)

现在,函数的这种包装的等价物analyze将使用另一个异步函数,或者更好,因为调用async函数将返回 a Promise,使用catcha 的方法Promise

analyze()
  .then(() => console.log('My work is done here'))
  .catch(ex => console.error(ex)); // NOTE: not throwing another exception
Run Code Online (Sandbox Code Playgroud)

catch更好的是一开始就不返回拒绝,从而使得analyze

async function analyze(stack, libraries) {
  try {
    const config = await buildConfiguration(stack, libraries);
    return await databaseInsertion(vulnsObject);
  } catch (err) {
    console.error(err); // not eating up good errors with something vague is always good
    return null; // or something else to signify that insert failed
  }
}
Run Code Online (Sandbox Code Playgroud)