如何修复Discord.js中catch函数无法阻断后续代码执行的bug
问题根因
message.guild.members.ban()是异步返回Promise的方法,原代码中.catch()内的return仅能退出catch绑定的回调函数,无法作用到外层同步执行的代码。写在Promise链外的message.reply()属于同步逻辑,会在ban请求发出后立刻执行,不会等待ban操作的最终结果,因此无论封禁成功还是失败,都会触发成功回复。
修复方法
推荐使用async/await写法,逻辑可读性最高,注意需要先把承载这段代码的消息事件回调标记为async:
// 事件回调示例:client.on('messageCreate', async (message) => { try { await message.guild.members.ban(args[0]) // 封禁成功后才会执行到此处,发送成功通知 message.reply({ embeds: [ new MessageEmbed() .setTitle('Ban') .setDescription(`User - <@${args[0]}> ban\nMod - ${message.author}\nReson - ${args.slice(1).join(' ')}`) ] }) } catch (err) { // 封禁失败进入错误分支,不会执行上面的成功通知逻辑 if (err.code === 10013 || err.code === 50035) { return message.channel.send({ embeds: [ new MessageEmbed() .setTitle('Oh no!') .setDescription('No user') .setColor('ff3333') ] }) } // 可在此补充其他错误场景处理,比如权限不足的提示 message.channel.send({ embeds: [ new MessageEmbed() .setTitle('Oh no!') .setDescription('Ban operation failed, please check bot permissions and target user role') .setColor('ff3333') ] }) }
如果不想用async/await,也可以用Promise链式调用,把成功逻辑放到.then()回调中,确保只有请求成功才执行:
message.guild.members.ban(args[0]) .then(() => { message.reply({ embeds: [ new MessageEmbed() .setTitle('Ban') .setDescription(`User - <@${args[0]}> ban\nMod - ${message.author}\nReson - ${args.slice(1).join(' ')}`) ] }) }) .catch(err => { if (err.code === 10013 || err.code === 50035) { return message.channel.send({ embeds: [ new MessageEmbed() .setTitle('Oh no!') .setDescription('No user') .setColor('ff3333') ] }) } message.channel.send({ embeds: [ new MessageEmbed() .setTitle('Oh no!') .setDescription('Ban operation failed, please check bot permissions and target user role') .setColor('ff3333') ] }) })
注意事项
- Promise回调内的
return仅能终止当前回调函数的执行,无法阻断外层同步代码的运行,涉及异步操作的后续逻辑不要写到Promise链外部 - 封禁功能建议补充前置校验:执行ban操作前先判断机器人本身是否拥有
BAN_MEMBERS权限,以及目标用户角色是否低于机器人角色,减少不必要的接口报错
内容的提问来源于stack exchange,提问作者Bohdan
相关产品推荐
相关产品推荐

