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

Express中出现Unhandled promise rejections错误,catch语句失效排查

解决Express中未处理Promise拒绝错误:无法读取undefined的address属性

问题根源

你的错误出在try代码块之外的表格匹配逻辑:

const tableAddress = tables.filter(table => table.id == tableId)[0].address
const team_ID = tables.filter(table => table.id == tableId)[0].id

当请求的tableId不存在于tables数组中时,filter会返回空数组,此时[0]就是undefined,访问它的address属性会直接抛出同步错误。而这部分代码不在try块内,所以后续的catch无法捕获这个错误,最终导致未处理的Promise拒绝(async函数会将同步错误自动包装为Promise拒绝)。

另外原代码还有一个潜在问题:不管try块是否出错,最后都会执行res.json(results),这会导致错误情况下重复发送响应,触发"Cannot set headers after they are sent to the client"错误。

修复方案

修改后的完整代码

app.get('/standings/:tableId', async (req, res) => {
  const tableId = req.params.tableId;
  const results = [];

  try {
    // 用find替代filter,直接获取匹配的表格对象,更高效
    const targetTable = tables.find(table => table.id === tableId);
    
    // 提前判断是否找到对应表格,返回明确的404错误
    if (!targetTable) {
      return res.status(404).json({ error: `找不到ID为${tableId}的联赛表格` });
    }

    const tableAddress = targetTable.address;
    const team_ID = targetTable.id;

    const result = await request.get(tableAddress);
    const $ = cheerio.load(result);

    $('#league-tables-wrapper > div > div.table-wrapper > table > tbody > tr').each((index, element) => {
      const tds = $(element).find("td");
      const rank = $(tds[0]).text();
      const team = $(tds[2]).text();
      const points = $(tds[10]).text();
      results.push({ rank, team, points });
    });

    // 仅在成功时返回结果
    res.json(results);
  } catch (error) {
    // 统一捕获所有错误:包括请求失败、DOM解析错误等
    res.status(500).json({ error: error.message });
  }
});

关键修改点

  1. 将表格匹配逻辑移入try块:确保所有同步错误都能被catch捕获
  2. 使用find替代filter:语义更明确(查找单个匹配项),性能更优
  3. 增加存在性检查:提前返回404错误,避免访问undefined属性
  4. 调整响应位置:仅在成功流程中返回结果,避免重复发送响应

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:25:24