我可以通过在 Promise 中抛出异常来中断 Javascript 吗?未处理的承诺拒绝警告

Can I interrupt Javascript by throwing an exception in a Promise? UnhandledPromiseRejectionWarning

我有一个简单的 Web 应用程序 运行 NodeJS 和 Express。它有一个外部第三方可以 POST 我们的 XML 文档的路由,然后我们将其转换为 JSON 然后保存到我们的 MongoDB 数据库。有些事情可能会出错:

XML 可能格式不正确

请求可能为空

外部第 3 方可能会向我们发送重复文件

与其拥有无穷无尽的 then() 块系列,越来越深,缩进越来越远,我想为每个可能的错误抛出异常,然后在顶层捕获这些错误并处理它们那里。

所以我们找到一个唯一的id,然后检查这个唯一的id是否已经在MongoDB:

// will throw an error if there is a duplicate
document_is_redundant(AMS_945, unique_id);

函数如下所示:

function document_is_redundant(this_model, this_unique_id) {

return this_model.findOne({ unique_id : this_unique_id })
.exec()
.then((found_document) => {
    // 2021-11-28 -- if we find a duplicate, we throw an error and handle it at the end
    // But remember, we want to return a HTTP status code 200 to AMS, so they will stop
    // re-sending this XML document.
    if (found_document != 'null') {
    throw new DocumentIsRedundantException(this_unique_id);
    }
});
// no catch() block because we want the exception to go to the top level
}

这给了我:UnhandledPromiseRejectionWarning

也许我想的太像 Java 而不是 Javascript,但我假设如果我没有 catch() 该函数中的异常,它会冒泡到顶层,这是我要处理它的地方。还假设它会在我调用函数的行中断代码流。

可悲的是,未捕获的异常不会中断执行的主线程,因此文档被保存,即使它是重复的。

所以我认为我可以完成这项工作的唯一方法是 return 函数中的 Promise,然后在调用 document_is_duplicate 函数后有一个 then() 块?

我不喜欢将 then() 块嵌套在 then() 块中,嵌套数层。这似乎是错误的代码。还有别的办法吗?

如果您的文档存在,不确定为什么要抛出错误。寻找它,如果存在,Mongoose 将 return 一个文档,如果不存在,则 null。然后简单地 await 结果。可以等待 Mongoose 方法,如果你添加 .exec() 它们甚至 return 一个真正的 Promise,这会让你的生活更轻松 :

const document_is_redundant = (this_model, unique_id) => this_model.findOne({ unique_id }).lean().exec();

// Now you use it this way
if( !(await document_is_redundant(AMS_945, unique_id))){ // If the returned value is not null
  console.log("Document is redundant! Aborting")
  return;
}
// Returned value was null
console.log("The document doesn't exist yet!")