javascript - 尽管有几个 `try`-`catch` 块,但仍获得 UnhandledPromiseRejectionWarning
问题描述
我正在使用一个封装了他们的 API 的 3rd 方模块。我有以下代码:
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
抓住这个?究竟什么是未处理的,以及如何实际处理?
解决方案
关键是 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.
推荐阅读
- javascript - if 语句 Firebase 函数的语法错误
- sql-server - 使用批量插入在 SQL Server 上上传数据并定义字段引用
- git - 摆脱少数提交
- angular - 在 Angular 页面中显示 Angular 代码和 HTML(未解析)
- javascript - 如何更改连接到使用 jquery 以动态形式选择更改的值?
- linux - 使用 sed 替换多词
- asp.net - web.config 将 http://www.name.it 重写为 https://www.name.com
- fedora - openCV 无法在 Fedora 28 上播放视频
- trustpilot - Trustpilot 邀请 api 奇怪的结果
- stripe-payments - 如何使用 webtask.io webhook 设置 Stripe Ideal