fetch failed at node:internal/deps/undici/undici:15845:13 at process.processTick...

2026年02月23日 23:04 error

错误信息

[AI] 流式请求异常: TypeError: fetch failed at node:internal/deps/undici/undici:15845:13 at process.processTicksAndRejections (node:internal/process/task_queues:103:5) at async chatWithAIStream (E:\TaoBaoFxiao\backend\src\services\aiService.ts:225:17) at async <anonymous> (E:\TaoBaoFxiao\backend\src\routes\ai.ts:245:7) { [cause]: ConnectTimeoutError: Connect Timeout Error (attempted address: api.openai.com:443, timeout: 10000ms) at onConnectTimeout (node:internal/deps/undici/undici:1690:23) at Immediate._onImmediate (node:internal/deps/undici/undici:1656:35) at process.processImmediate (node:internal/timers:504:21) { code: 'UND_ERR_CONNECT_TIMEOUT' } }

AI 解决方案

代码糕手 - 报错分析报告错误翻译

原文:TypeError: fetch failed
译文:类型错误:fetch 请求失败

根本原因:网络连接超时,无法连接到 OpenAI API 服务器。

具体分析

  • 错误类型TypeError: fetch failed 表示 fetch API 调用失败

  • 底层原因ConnectTimeoutError 连接超时错误

  • 关键信息

  • - 目标地址:api.openai.com:443
    - 超时时间:10000ms (10秒)
    - 错误代码:UND_ERR_CONNECT_TIMEOUT
  • 发生位置aiService.ts 第 225 行的 chatWithAIStream 函数中解决方案
  • 方案一:增加超时时间(推荐)


    // 在 aiService.ts 中的 fetch 调用处修改
    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${apiKey}`
      },
      body: JSON.stringify(payload),
      // 增加超时时间
      signal: AbortSignal.timeout(30000) // 增加到 30 秒
    });
    

    方案二:添加重试机制


    // 创建带重试的 fetch 函数
    async function fetchWithRetry(url: string, options: RequestInit, maxRetries = 3): Promise<Response> {
      for (let i = 0; i < maxRetries; i++) {
        try {
          const controller = new AbortController();
          const timeoutId = setTimeout(() => controller.abort(), 15000);
          
          const response = await fetch(url, {
            ...options,
            signal: controller.signal
          });
          
          clearTimeout(timeoutId);
          return response;
        } catch (error) {
          if (i === maxRetries - 1) throw error;
          console.log(`请求失败,第 ${i + 1} 次重试...`);
          await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); // 指数退避
        }
      }
      throw new Error('所有重试均失败');
    }
    
    // 使用方式
    const response = await fetchWithRetry(apiUrl, {
      method: 'POST',
      headers: headers,
      body: JSON.stringify(payload)
    });
    

    方案三:检查网络连接


    // 在发起请求前检查网络连接
    async function checkNetworkConnection(): Promise<boolean> {
      try {
        const controller = new AbortController();
        const timeoutId = setTimeout(() => controller.abort(), 5000);
        
        const response = await fetch('https://api.openai.com/', {
          method: 'HEAD',
          signal: controller.signal
        });
        
        clearTimeout(timeoutId);
        return response.ok;
      } catch {
        return false;
      }
    }
    
    // 使用前检查
    if (!await checkNetworkConnection()) {
      throw new Error('网络连接异常,请检查网络设置');
    }
    

    ##### 1.警

    // 添加请求监控
    const startTime = Date.now();
    try {
      const response = await fetch(apiUrl, options);
      const duration = Date.now() - startTime;
      
      // 记录请求耗时
      console.log(`API 请求耗时: ${duration}ms`);
      
      if (duration > 5000) {
        console.warn('API 响应较慢,建议优化');
      }
      
      return response;
    } catch (error) {
      // 记录错误信息到日志系统
      console.error('API 请求失败:', {
        error: error.message,
        url: apiUrl,
        timestamp: new Date().toISOString()
      });
      throw error;
    }
    

    配置管理最佳实践

  • 环境变量配置:将 API 端点、超时时间等配置提取到环境变量中

  • 连接池管理:考虑使用 HTTP 客户端库(如 axios)替代原生 fetch,以获得更好的连接管理

  • 故障转移:配置备用 API 端点或服务提供商

  • 网络诊断工具:使用 pingtraceroutecurl 定期检查 API 服务的可达性
  • 推荐工具:


    -
    :更强大的 HTTP 客户端,内置超时和重试机制
    -或 New Relic:错误监控和性能分析平台PostmanInsomnia:API 测试工具,用于验证端点可达性


    总结:这是一个