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 }); } });
关键修改点
- 将表格匹配逻辑移入try块:确保所有同步错误都能被catch捕获
- 使用find替代filter:语义更明确(查找单个匹配项),性能更优
- 增加存在性检查:提前返回404错误,避免访问undefined属性
- 调整响应位置:仅在成功流程中返回结果,避免重复发送响应
内容的提问来源于stack exchange,提问作者Imad Eddine
相关产品推荐
相关产品推荐

