Telegraf.js错误处理问题:TelegramError 400无法找到待删消息
解决方案
1. 给异步操作添加await,确保错误被捕获
你的ctx.deleteMessage()是异步函数,但未添加await,导致try/catch无法捕获异步错误,最终触发未处理的Promise拒绝,引发Nodemon崩溃。修改代码如下:
bot.action("clear", async ctx => { const sentMsg = await bot.telegram.sendMessage(ctx.chat.id, "Clearing console"); const id = sentMsg.message_id; console.log(id); for(let i = 1; i <= 100; i++ ){ // 从1开始,优先删除历史消息,最后处理提示消息 try { await ctx.deleteMessage(id - i); // 添加await捕获异步错误 } catch (error) { // 仅在遇到非"消息不存在"的错误时终止循环 if (!(error instanceof Error) || !error.message.includes("message to delete not found")) { console.log(error); break; } // 消息不存在则跳过,继续尝试删除下一条 console.log(`消息 ${id - i} 不存在,跳过`); } } // 最后删除提示消息 try { await ctx.deleteMessage(id); } catch (err) { console.log("删除提示消息失败:", err); } });
2. 调整循环逻辑,避免无效消息ID
- 原代码从
i=0开始,首先删除刚发送的提示消息,后续id-i会很快变成无效ID(比如i超过id时ID为负数),引发大量400错误。 - 改为从
i=1开始,先清理历史消息,最后主动删除提示消息,逻辑更合理。
3. 优化全局错误捕获
确保全局bot.catch能处理所有未捕获的错误,可修改为:
const bot: Telegraf<Context> = new Telegraf(token); bot.catch((err, ctx) => { console.log(`全局捕获错误: ${err.message}`, err); });
核心还是要在action内部处理好异步错误,减少错误冒泡到全局的情况。
额外注意事项
- Telegram API限制:机器人仅能删除自己发送的消息,或在超级群组/频道中删除有权限的消息。若尝试删除其他用户的消息,同样会返回400错误,需确认使用场景权限。
- 循环次数:
i <= 100会尝试删除100条消息,若聊天历史不足100条,会出现大量"消息不存在"的错误,可根据实际情况调整循环上限,或改为连续遇到几条不存在的消息后再终止循环。
内容的提问来源于stack exchange,提问作者Hadi Yahia
相关产品推荐
相关产品推荐

