You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js持续调用外部API出现TypeError: terminated错误求助

解决SocketError: other side closed错误的排查与修复方案

问题本质

这个错误是对方服务主动关闭了TCP连接,可能发生在请求发送中、响应接收过程里,或是连接闲置超时。从错误栈的字节数据(bytesWritten: 1594938、bytesRead: 12318698)来看,请求/响应数据量较大,大概率和大体积数据传输、连接复用规则、服务端限流策略有关。

排查步骤

  • 验证请求数据合规性
    确认payload的字段类型、嵌套结构、数据长度是否符合目标API的要求。大体积请求容易触发服务端的超时或大小限制,导致对方直接断连。
  • 添加请求超时控制
    当前fetch调用未设置超时,一旦服务端处理缓慢或网络波动,连接可能因闲置被关闭。给请求加上超时时间,避免无限制挂起:
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 30000); // 30秒超时
    
    try {
      const response = await fetch(url, {
        method: "POST",
        headers: headers,
        body: JSON.stringify(payload),
        signal: controller.signal
      });
      // 处理响应逻辑
    } catch (error) {
      if (error.name === 'AbortError') {
        console.log('请求超时,已主动终止');
      } else {
        throw error;
      }
    } finally {
      clearTimeout(timeoutId);
    }
    
  • 测试连接复用影响
    Node.js的fetch基于undici,默认复用TCP连接。如果持续发送大量请求,可能触发服务端的连接数限制,导致旧连接被强制关闭。可以临时禁用连接复用测试:
    import { Agent } from 'undici';
    
    await fetch(url, {
      method: "POST",
      headers: headers,
      body: JSON.stringify(payload),
      dispatcher: new Agent({ keepAliveTimeout: 0 })
    });
    
    (需先安装undici包:npm install undici)
  • 排查服务端限流规则
    查看目标API的官方文档,确认是否有请求频率、并发数、单请求数据量的限制。超出限制时,服务端可能直接断连而不返回标准错误响应。可以添加请求间隔或重试机制:
    const retry = async (fn, retries = 3, delay = 1000) => {
      try {
        return await fn();
      } catch (error) {
        if (retries > 0 && error.cause?.code === 'UND_ERR_SOCKET') {
          await new Promise(resolve => setTimeout(resolve, delay));
          return retry(fn, retries - 1, delay * 2);
        }
        throw error;
      }
    };
    
    // 使用重试逻辑发起请求
    const response = await retry(() => fetch(url, {
      method: "POST",
      headers: headers,
      body: JSON.stringify(payload)
    }));
    
  • 记录错误上下文信息
    在catch块中记录请求的URL、payload大小、时间戳等信息,方便定位是否是特定请求触发的问题:
    try {
      // 请求代码
    } catch (error) {
      console.error(`请求失败时间: ${new Date().toISOString()}`);
      console.error(`目标URL: ${url}`);
      console.error(`请求体大小: ${JSON.stringify(payload).length}字节`);
      console.error(`错误详情:`, error);
    }
    

修复建议

  1. 强制设置请求超时:避免连接因长期闲置被服务端关闭。
  2. 添加指数退避重试:针对SocketError这类网络/连接错误进行重试,提升请求容错性。
  3. 拆分大体积请求:如果payload数据量过大,尝试分批次发送,减少单次请求的数据传输压力。
  4. 调整连接复用参数:若确认是连接复用导致的问题,可适当调整undici的keepAliveTimeout或maxConnections参数,匹配服务端的连接策略。

内容的提问来源于stack exchange,提问作者TungTung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 08:20:21