node.js - 强制 API 超时时 Node JS 中的套接字挂断错误

标签 node.js sockets node-modules node-request node-https

我正在使用 Node JS (v8.12) 中的请求模块来调用第三方 API。由于 API 不是很可靠并且由于缺乏更好的选项,我会在 2 秒后超时调用,以防 API 没有响应。但是这样做会产生一个套接字挂起错误。下面是使用的代码和堆栈跟踪

const options = {
    url: resource_url,
    rejectUnauthorized: false,
    timeout: 2000,
    method: 'GET',
    headers: {
        'content-Type': 'application/json',
    }
};

return new Promise(function (resolve, reject) {
    request(options, function (err, res, body) {
        if (!err) {
            resolve(JSON.parse(body.data));                 
        } else {
            if (err.code === 'ETIMEDOUT' || err.code == 'ESOCKETTIMEDOUT') {
                resolve(someOldData);
            } else {
                resolve(someOldData);
            }
        }
    });
});


Error: socket hang up
    at createHangUpError (_http_client.js:331:15)
    at TLSSocket.socketCloseListener (_http_client.js:363:23)
    at scope.activate (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/base.js:54:19)
    at Scope._activate (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/async_hooks.js:51:14)
    at Scope.activate (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/base.js:12:19)
    at TLSSocket.bound (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/base.js:53:20)
    at emitOne (events.js:121:20)
    at TLSSocket.emit (events.js:211:7)
    at _handle.close (net.js:554:12)
    at TCP.done [as _onclose] (_tls_wrap.js:356:7)
在做了一些阅读和研究后,我发现了这个 article指出一个类似的问题,所以我切换到 http 模块,如文章中的解决方案之一所述。但是切换到 http 模块也没有解决问题。下面是使用 http 和堆栈跟踪的代码实现。
let responseData;
const requestOptions = {
    hostname: resource_host,
    path: resource_path,
    method: 'GET',
    timeout: 2000,
};

return new Promise((resolve, reject) => {
    const requestObject = http.request(requestOptions, (responseObj) => {
        responseObj.setEncoding('utf8');
        responseObj.on('data', (body) => {          
           responseData = body;
        });

        responseObj.on('end', () => {
            resolve(responseData);
        });
    });

    requestObject.on('error', (err) => {
        responseData = someOldData;
        resolve(responseData);
    });

    requestObject.on('timeout', () => {
        responseData = someOldData;
        requestObject.abort();
    });

    requestObject.end();
});

Error: socket hang up
    at connResetException (internal/errors.js:608:14)
    at Socket.socketCloseListener (_http_client.js:400:25)
    at <trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/base.js:54:19
    at Scope._activate (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/async_hooks.js:51:14)
    at Scope.activate (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/base.js:12:19)
    at Socket.bound (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/base.js:53:20)
    at Socket.emit (events.js:322:22)
    at Socket.EventEmitter.emit (domain.js:482:12)
    at TCP.<anonymous> (net.js:672:12)
我通过网络浏览了多个 SO 帖子和各种其他资源,但我无法解决这个问题。
可能是因为第三方,因为我还尝试通过创建一个虚拟服务器来重现该问题,该服务器在请求被触发后休眠一段时间并超时该请求但无法重现该问题。
我将非常感谢在这方面的任何帮助。

最佳答案

使用 http 模块时删除超时事件 block 中的 requestObject.abort() 可解决此问题。

关于node.js - 强制 API 超时时 Node JS 中的套接字挂断错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61784461/

相关文章:

javascript - 如何使用 Node 写入文件

javascript - 使用 async/await Promise NodeJS 获取交易哈希

node.js - Visual Studio 发布按钮被禁用?

iphone - 在iPhone中监听TCP端口

c - 从套接字缓冲区逐行读取

java - 在几个 java 套接字中测量带宽/速度?

node.js - 安装 Node 模块 xml-stream

javascript - PostgreSQL未连接到Heroku

node.js - face-api.js 从磁盘加载图像文件

javascript - 归内还是外为?