【问题标题】:Getting UnhandledPromiseRejectionWarning despite several `try`-`catch` blocks尽管有几个 `try`-`catch` 块,但仍获得 UnhandledPromiseRejectionWarning
【发布时间】:2019-07-09 00:43:56
【问题描述】:

我正在使用一个封装了他们的 API 的第 3 方模块。我有以下代码:

const api = require('3rdpartyapi');

 async function callAPI(params) {
  try {
    let result = await api.call(params);
    return result;
  }
  catch(err) {
    throw err;  //will handle in other function
  }
 }
 
 async function doSomething() {
  try {
    //...do stuff
    let result = await callAPI({a:2,b:7});
    console.log(result);
  }
  catch(err) {
    console.error('oh no!', err);
  }
}

尽管有两个try-catch 块,但第 3 方 API 在失去与 homebase 的连接时(经常发生:(),爆炸:

(node:13128) UnhandledPromiseRejectionWarning: FetchError: request to https://www.example.com failed, reason: getaddrinfo ENOTFOUND

接着是:

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(). (rejection id: 1)

我的try-catch 怎么都没人听懂这个?究竟什么是未处理的,以及如何实际处理?

【问题讨论】:

  • 如果你确定你正在处理你在另一个函数中抛出的错误,那么,在第 3 方 api 中是否存在一些未处理的承诺拒绝?你能跟踪 api.call() 函数,看看你是否发现任何未处理的承诺?
  • @BryanOliveira 不,我没有代码 - 但问题仍然存在:如何在不同的函数中处理它?我的一个 catch 块不应该抓住它吗?

标签: javascript node.js promise async-await


【解决方案1】:

关键是 await 只将“第一层”拒绝转换为错误,但是 promise 内部可以有 promise,并且它们的库可能无法捕获内部拒绝。我已经做了一个概念证明 3rdpartyapi,它可以触发你看到的行为:


(async function () {

// mock 3rdpartyapi
var api = {
    call: async function(){
        await new Promise((resolve, reject) => {
            // why wrap a promise here? but i don't know
            new Promise((innerResolve, innerReject) => {
                innerReject('very sad'); // unfortunately this inner promise fail
                reject('this sadness can bubble up');
            })
        })
    }
};

// your original code
async function callAPI(params) {
    try {
        let result = await api.call(params);
        return result;
    } catch (err) {
        throw err; //will handle in other function
    }
}

async function doSomething() {
    try {
        //...do stuff
        let result = await callAPI({
            a: 2,
            b: 7
        });
        console.log(result);
    } catch (err) {
        console.error('oh no!', err);
    }
}

doSomething();

})();

输出:

$ node start.js
oh no! this sadness can bubble up
(node:17688) UnhandledPromiseRejectionWarning: very sad
(node:17688) 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(). (rejection id: 1)
(node:17688) [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.

【讨论】:

  • 哎哟!有什么办法我仍然可以捕捉到内心的拒绝吗?归根结底,我需要防止崩溃并向我的客户报告错误。
  • 顺便说一句,在您的示例代码中,“哦,不!”被打印出来,即错误被更高级别捕获。就我而言,我从未见过它。
  • 你可以看到unhandledRejection event。对于您的情况,可能是第 3 方库在 innerReject 行上有 return,因此永远不会调用第一层的 reject
  • 感谢您的启发性资源。那里的人声称要抑制 unhandledException 事件,您所要做的就是添加catch。由于 2 我没有工作,我是否可以得出结论,在第 3 方修复他们的代码以处理他们的内部问题之前,我无能为力?
  • 已经做到了。他们说他们会让我访问他们的 git,我应该找到错误并打开 PR。不知道我现在正在为他们工作...... :)。无论如何,感谢您的帮助、演示和链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多