调用interaction.deferReply()仍遇discord.js交互异常,部署后频发
排查Discord.js中deferReply后仍出现Unknown Interaction异常的问题
问题描述
在使用discord.js开发机器人时,已调用interaction.deferReply(),但偶尔触发"Unknown Interaction Exception"和"has not been sent or preferred Exception"异常。本地运行无问题,但在托管服务商环境下频繁报错,相关代码如下:
async execute(interaction) { interaction.deferReply(); let name_tag = interaction.options.getString('검색어'); if (name_tag === '*'){ name_tag = ''; } const result = await request(`https://api.the-finals-leaderboard.com/v1/leaderboard/s2/crossplay?name=${name_tag}`) const rank_data= await result.body.json() const page_length = rank_data.count; if (page_length === 0) { interaction.editReply("검색 결과가 없습니다 (ㅠ ㅠ)"); return; } let now_page = 0; let data = rank_data.data[now_page] const response = await interaction.editReply({ embeds: [createEmbed(data)], components: [createPageButton(data, now_page, page_length)], }); const collector = response.createMessageComponentCollector({ fillter: i => i.user.id === interaction.user.id, componentType: ComponentType.Button, idle: 20_000 }); collector.on('collect', async i => { const component = i.component; now_page += Number(component.customId.replaceAll('page_count_', "")); data = rank_data.data[now_page] await i.update({ embeds: [createEmbed(data)], components: [createPageButton(data, now_page, page_length)], }); }); collector.on('end', async () => { response.edit({ components: []}) }) }
核心故障原因与修复方案
1. 未等待deferReply异步操作完成
interaction.deferReply()是异步方法,原代码未加await就执行后续逻辑,在网络延迟较高的托管环境中,Discord服务器可能还未确认延迟回复,后续的editReply就已发起请求,导致交互状态不一致,触发异常。
修复:给deferReply添加await:
await interaction.deferReply();
2. 收集器选项拼写错误
代码中createMessageComponentCollector的fillter是拼写错误,正确应为filter,这会导致收集器无法正确过滤用户交互,引发后续组件操作异常。
修复:修正拼写:
const collector = response.createMessageComponentCollector({ filter: i => i.user.id === interaction.user.id, componentType: ComponentType.Button, idle: 20_000 });
3. 未处理外部API请求异常与超时
托管环境网络质量可能不如本地,调用外部API时若延迟过高或请求失败,会导致从defer到editReply的时间过长,甚至直接中断流程,引发交互超时。
修复:添加超时设置与异常捕获:
try { // 给API请求添加10秒超时限制 const result = await request(`https://api.the-finals-leaderboard.com/v1/leaderboard/s2/crossplay?name=${name_tag}`, { timeout: 10000 }); const rank_data = await result.body.json(); // 后续逻辑... } catch (err) { console.error("API请求或处理出错:", err); // 出错时给用户反馈,避免交互挂起 try { await interaction.editReply("검색 중 오류가 발생했습니다. 다시 시도해주세요!"); } catch (editErr) { console.log("编辑错误消息失败:", editErr); } }
4. 未做页码边界检查
当用户点击按钮时,now_page可能超出rank_data.data的数组范围,导致数据访问错误,进而引发后续交互异常。
修复:添加边界检查:
now_page += Number(component.customId.replaceAll('page_count_', "")); // 确保页码在0到page_length-1之间 now_page = Math.max(0, Math.min(now_page, page_length - 1)); data = rank_data.data[now_page];
5. 收集器结束事件未处理消息过期情况
当收集器超时结束时,若消息已被用户删除或Discord服务器已回收交互,调用response.edit会抛出异常。
修复:添加异常捕获:
collector.on('end', async () => { try { await response.edit({ components: [] }); } catch (err) { console.log("收集器结束时编辑消息失败:", err); } });
托管环境额外排查项
- 网络稳定性:测试托管服务器到Discord API(
discord.com、discordapp.com)和外部API的网络延迟,延迟过高会导致交互请求超时。 - 资源限制:检查托管服务商是否有CPU、内存或带宽限制,资源不足会导致代码执行缓慢,超过Discord的交互时间窗口。
- 系统时间同步:确保托管服务器时间与Discord服务器时间同步,极端时间偏差可能影响交互签名验证。
- 防火墙/代理:确认托管环境未阻止与Discord API的通信,将Discord相关域名加入白名单。
内容的提问来源于stack exchange,提问作者Cupelt
相关产品推荐
相关产品推荐

