Discord.js机器人本地运行正常 Heroku部署报UnhandledPromiseRejection错误
问题解决办法
- 报错的根源是
message.reply()、message.channel.send()都是Discord.js提供的异步方法,调用后会返回Promise对象,你当前代码没有对这些Promise的异常情况做捕获处理,一旦调用失败(比如机器人无频道发消息权限、网络波动、Discord接口限流)就会触发未处理的Promise拒绝报错,本地能正常运行是因为测试场景下所有接口调用都成功,部署到Heroku后环境差异触发了异常场景。 - 你之前给异步函数加
.catch()报错是因为添加位置错误,不需要加在collector的事件回调末尾,要加在每个返回Promise的异步调用后面。
修复后代码示例
collector.on('end', collected => { //Respond Collector let newContentInput = ''; collected.forEach((message) => { newContentInput += message.content.split(" "); }); //Proccess Failed if (collected.size === 0) { message.reply(`Proses gagal :frowning::thumbsdown:`) // 新增catch捕获异常 .catch(err => console.log('发送回复失败:', err)); return; } //Proccess Canceled let x = 0; if (cancel(newContentInput,x) === 1) return; //DupBadWord Check let newContent = newContentInput.split(','); knwContent = []; unkContent = []; count = newContent.length; let fProc = Boolean; fProc = false; let sProc = Boolean; sProc = false; //Check new input = Known/Unknown function knownBadWord (i) { knownCheck = badWordsDB .includes(newContent[i].toLowerCase()); return knownCheck; }; for (let i = 0; i < count; i++) { if (knownBadWord(i)) { knwContent.push(newContent[i]); //Identified as known word fProc = true; } else { unkContent.push(newContent[i]); //Identified as unknown word sProc = true; } } fText = `sudah ada di dalam ${haram} :sob::thumbsdown:`; sText = `akan ditambahkan ke ${haram} :weary::ok_hand:`; sConf = `Apakah anda yakin? \`YES\` || \`NO\``; if (fProc === false) { message.channel.send(`Siap! Kata \`${unkContent}\` ${sText}\n${sConf}`) // 新增catch捕获异常 .catch(err => console.log('发送频道消息失败:', err)); confirmation(unkContent,count,code); } else if (fProc === true && sProc === true) { message.channel.send(`Kata \`${unkContent}\` ${sText}` + `\nNamun kata \`${knwContent}\` ${fText}\n${sConf}`) // 新增catch捕获异常 .catch(err => console.log('发送频道消息失败:', err)); confirmation(unkContent,count,code); } else if (fProc === true) { message.channel.send(`Maaf! Kata \`${knwContent}\` ${fText}`) // 新增catch捕获异常 .catch(err => console.log('发送频道消息失败:', err)); } })
额外优化建议
- 如果你使用的
confirmation函数内部也有发消息、数据库操作这类异步逻辑,也要给对应的Promise添加.catch()捕获异常。 - 可以添加全局异常捕获兜底,避免遗漏的异常导致进程退出:
process.on('unhandledRejection', err => { console.error('未处理的Promise拒绝:', err); });
内容的提问来源于stack exchange,提问作者Senzawa
相关产品推荐
相关产品推荐

