节点给出UnhandledPromiseRejection警告,当我确定*我正在接受拒绝
我正在使用node-libcurl。我有一个小模块,我有一个curl请求队列。以下是实际发出curl请求的函数:
const Curl = require('node-libcurl').Curl;
let timeoutCount = 0;
function _getOData(url) {
const curl = new Curl();
return new Promise((resolve, reject) => {
curl.setOpt(Curl.option.URL, url);
curl.setOpt(Curl.option.HTTPAUTH, Curl.auth.NTLM);
curl.setOpt(Curl.option.SSL_VERIFYPEER, false);
curl.setOpt(Curl.option.SSL_VERIFYHOST, false);
curl.setOpt(Curl.option.POST, 0);
curl.setOpt(Curl.option.HTTPHEADER, ['Accept: application/json']);
let done = false;
curl.on('end', function (statusCode, body, headers) {
done = true;
const retObj = JSON.parse(body);
resolve(retObj);
curl.close();
});
curl.on('error', function (e) {
done = true;
reject(e);
curl.close();
});
curl.perform();
setTimeout(() => {
if (!done) {
timeoutCount++;
reject(new Error(`request timed out: ${timeoutCount}`));
}
},1000*10);
})
}
我一直在控制台中收到这个错误:(node:26616) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 6): Error: request timed out
- 所以我添加了timeoutCount,因为我确定我正在捕获所有Promise错误,尽管得到了这个警告。
每次调用_getOData函数都发生在队列逻辑中,特别是这段代码是调用_getOData的唯一代码:
const p = _getOData(nextObj.url);
p.then(nextObj.cb);
p.catch((e) => {
if (e.message.includes("request timed out")) {
queue.add(nextObj.url, nextObj.cb, nextObj.ecb);
return true;
} else {
nextObj.ecb(e);
return false;
}
});
所以我在e.message.includes("request timed out")
之后设置了一个断点,它每次都会在请求超时错误发生时点击,所以我知道没有“未处理的拒绝承诺”。每一个承诺拒绝都会通过这个捕获。我检查变量是否在那里打破以确保timeoutCount存在,并且它始终是,然后它仍然总是作为未处理的承诺拒绝记录到控制台。
这里发生了什么?
回答如下:您可能正在捕获队列中的拒绝而不是堆栈上的拒绝。您使用以下代码获得该错误(警告):
var p = Promise.reject("hello world");//do not catch on the stack
setTimeout(
x=>p.catch(err=>console.log("catching:",err))//caught error on queue
,100
);
如果要捕获队列中的拒绝,则可以执行以下操作:
saveReject = p =>{
p.catch(ignore=>ignore);
return p;//catch p but return p without catch
}
var p = saveReject(Promise.reject("hello world"));//creating promise on the stack
setTimeout(
x=>p.catch(err=>console.log("catching:",err))//caught error on queue
,100
);
有关队列和堆栈的信息可以在here找到。