节点发出 UnhandledPromiseRejection 警告,当我*确定*我收到拒绝时 [英] Node giving UnhandledPromiseRejection warning, when I'm *sure* I'm catching the rejection

查看:99
本文介绍了节点发出 UnhandledPromiseRejection 警告,当我*确定*我收到拒绝时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 node-libcurl.我有一个小模块,其中有一个用于 curl 请求的队列.下面是实际发出 curl 请求的函数:

I'm using node-libcurl. I've got a little module in which I have a queue for curl requests. Here's what the function looks like to actually make the curl request:

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: UnhandledPromiseRejectionWarning: Unhandled promise reject (rejection id: 6): Error: request timed out -- 所以我添加了 timeoutCount 因为尽管收到此警告,但我确信我捕获了所有 Promise 错误.

I kept getting this error in the console: (node:26616) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 6): Error: request timed out -- so I added the the timeoutCount because I was certain I was catching all Promise errors, despite getting this warning.

对 _getOData 函数的每一次调用都发生在队列逻辑内部,具体来说,这段代码是唯一调用 _getOData 的代码:

Every single call to the _getOData function happens inside the queue logic, specifically this code is the only code to call _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 存在,并且始终存在,然后它仍然总是作为未处理的承诺拒绝记录到控制台.

So I set a breakpoint after e.message.includes("request timed out") and it hits there every single time a request timed out error happens, so I KNOW FOR SURE there are no 'unhandled promise rejections'. Every single promise rejection goes through that catch. I inspect the variable when it breaks there to make sure that the timeoutCount is there, and it always is, and then it still always gets logged to the console as an unhandled promise rejection.

这是怎么回事?

推荐答案

您可能在队列中而不是在堆栈中捕获拒绝.您使用以下代码收到该错误(警告):

You're probably catching the reject on the queue and not on the stack. You get that error (warning) with the following code:

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
);

如果您要捕获队列中的拒绝,则可以执行以下操作:

If you're going to catch the reject on the queue then you can do the following:

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
);

可以在此处找到有关队列和堆栈的信息.

Information about queue and stack can be found here.

这篇关于节点发出 UnhandledPromiseRejection 警告,当我*确定*我收到拒绝时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆