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

Fetch请求遇ECONNREFUSED时try/catch未捕获,致服务器崩溃求助

问题分析与解决方案

问题原因

你遇到的FetchError导致全站崩溃,核心问题不是getTournamentNews内部的try/catch失效,而是调用这个异步函数的代码没有正确处理Promise的拒绝状态。

在Node.js环境中,未被捕获的Promise拒绝会触发进程终止(默认行为)。如果Express启动脚本里调用getTournamentNews()时,既没有用await包裹在try/catch中,也没有附加.catch()处理错误,那么当服务器宕机触发网络错误时,这个未处理的Promise拒绝会直接导致Node进程崩溃,进而全站无法运行。

另外补充一点:你的代码未处理HTTP错误(比如500、404),因为fetch只有在网络层面失败时才会reject,HTTP状态码错误不会触发catch,这可能导致后续data.json()或数据处理逻辑出错,虽不是本次崩溃的主因,但也是潜在风险。

解决方案

1. 修复调用处的错误处理

确保在Express启动脚本中调用getTournamentNews时,正确处理异步错误:

// 示例修改后的启动逻辑
async function initScripts() {
  try {
    await getTournamentNews();
    // 执行其他初始化逻辑
  } catch (e) {
    console.error('初始化锦标赛新闻失败:', e);
    // 忽略错误,继续执行后续流程
  }
}

// 调用初始化函数时也要兜底处理错误
initScripts().catch(e => console.error('初始化脚本整体出错:', e));

2. 优化getTournamentNews的健壮性

增加网络超时与HTTP错误处理

给fetch添加超时配置,同时判断HTTP响应状态,避免无效数据进入后续逻辑:

async function getTournamentNews() {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), 5000); // 5秒超时

  try {
    let response = await fetch(`${process.env.WP_URL}/wp-json/wp/v2/posts/?per_page=10&_embed&_fields=content.rendered,categories&categories=638`, {
      signal: controller.signal
    });

    clearTimeout(timeoutId);

    // 主动处理HTTP错误状态
    if (!response.ok) {
      throw new Error(`HTTP请求失败,状态码: ${response.status}`);
    }

    let data = await response.json();
    let dataObjectToArray = Object.values(data);
    // 用可选链避免属性不存在时抛出错误
    let sortedData = dataObjectToArray.map(item => ({
      content: item.content?.rendered,
      category: item.categories
    }));
    let clientNewsData = sortedData.filter(article => article.category?.[1] !== 284);
    return clientNewsData;
  } catch (e) {
    console.error('获取锦标赛新闻失败:', e);
    return null;
  }
}

增加重试逻辑(可选)

如果需要在服务器恢复时自动重试,可以添加简单的重试机制:

async function getTournamentNews(retries = 2) {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), 5000);

  try {
    let response = await fetch(`${process.env.WP_URL}/wp-json/wp/v2/posts/?per_page=10&_embed&_fields=content.rendered,categories&categories=638`, {
      signal: controller.signal
    });

    clearTimeout(timeoutId);

    if (!response.ok) {
      throw new Error(`HTTP请求失败,状态码: ${response.status}`);
    }

    let data = await response.json();
    let dataObjectToArray = Object.values(data);
    let sortedData = dataObjectToArray.map(item => ({
      content: item.content?.rendered,
      category: item.categories
    }));
    let clientNewsData = sortedData.filter(article => article.category?.[1] !== 284);
    return clientNewsData;
  } catch (e) {
    console.error(`获取锦标赛新闻失败,剩余重试次数: ${retries}`, e);
    if (retries > 0) {
      await new Promise(resolve => setTimeout(resolve, 1000)); // 间隔1秒重试
      return getTournamentNews(retries - 1);
    }
    return null;
  }
}

关键注意点

  • 异步函数的错误必须被显式捕获,无论是用await + try/catch还是.then().catch(),否则Node.js进程会因未处理的Promise拒绝而崩溃;
  • fetch不会因HTTP错误状态码reject,必须手动判断response.ok;
  • 使用可选链操作符?.避免数据结构异常导致的后续代码报错;
  • 超时配置可以防止请求因服务器无响应而长时间挂起。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 08:10:28