Node.js调用第三方API时服务崩溃 报ETIMEDOUT连接超时错误
问题描述
现有POST接口逻辑如下:
app.post("/", (req, res) => { const origin = req.body.origin; const destination = req.body.destination; const urlOri = "https://api.openweathermap.org/data/2.5/weather?q=" + origin + "&APPID={mykey}" https.get(urlOri, function (response) { console.log(response); }) });
服务启动后调用该接口会触发未捕获错误导致服务崩溃,错误信息如下:
Server started on port 443 events.js:292 throw er; // Unhandled 'error' event ^ Error: connect ETIMEDOUT 178.128.25.248:443 at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1146:16) Emitted 'error' event on ClientRequest instance at: at TLSSocket.socketErrorListener (_http_client.js:469:9) at TLSSocket.emit (events.js:315:20) at emitErrorNT (internal/streams/destroy.js:106:8) at emitErrorCloseNT (internal/streams/destroy.js:74:3) at processTicksAndRejections (internal/process/task_queues.js:80:21) { errno: -4039, code: 'ETIMEDOUT', syscall: 'connect', address: '178.128.25.248', port: 443 }
相同代码在其他设备可正常运行,更换request、axios等请求库后仍然复现相同报错。
排查解决步骤
- 先做基础网络连通性验证:在本机命令行执行
curl -v https://api.openweathermap.org,如果curl请求也超时,问题出在网络层面,和Node.js代码、选用的请求库没有关系。 - 优先检查代理配置:这类访问境外接口超时的问题,80%以上是代理配置不全导致——浏览器能打开对应网站不代表终端/Node进程能访问,Node默认不会自动读取系统代理,需要手动给请求添加代理参数,或者在启动服务时配置
HTTP_PROXY、HTTPS_PROXY环境变量指向本地代理端口。 - 检查拦截规则:查看本机防火墙、杀毒软件、办公网安全策略是否拦截了Node.js进程的出站请求,或者直接封禁了openweathermap对应的IP段,可临时关闭防火墙测试是否恢复。
- 排查DNS解析异常:执行
nslookup api.openweathermap.org查看返回的IP地址,如果和报错中的178.128.25.248不一致、或者解析超时,可将本机DNS更换为公共DNS(114.114.114.114、8.8.8.8)后重试。 - 补全错误监听逻辑:不管网络问题是否解决,Node.js的所有网络请求都必须绑定
error事件监听,否则网络异常时会直接抛出未捕获错误导致整个服务崩溃,修改参考代码如下:
const weatherReq = https.get(urlOri, function (response) { // 原有响应处理逻辑 let data = '' response.on('data', chunk => data += chunk) response.on('end', () => res.send(data)) }) // 捕获请求错误,避免进程退出 weatherReq.on('error', (err) => { res.status(500).send({ msg: '请求天气服务失败', err: err.message }) })
- 无需优先排查API Key配置:当前报错是TCP连接阶段超时,还没到接口鉴权环节,API Key错误只会返回401状态码,不会触发连接超时。
内容的提问来源于stack exchange,提问作者Rishabhanand Jha
相关产品推荐
相关产品推荐

