discord.js v12中如何捕获错误并将其发送给机器人所有者?
问题核心原因
你当前的错误捕获逻辑失效的核心原因是try/catch的包裹位置错误。你现在把try写在了注册命令的代码外层,注册命令时只是把回调函数存起来,不会执行回调内部的代码,只有当用户触发对应命令时回调才会执行,此时抛出的错误自然不会被外层的try捕获。
修复方案
方案1:修改单个命令的写法,在回调内部加错误捕获
如果不需要全局统一处理,只需要给指定命令加错误捕获,直接把try/catch写到命令回调函数内部即可:
command(client, 'test', (message) => { try { // 命令所有业务逻辑写在try块内 CatchThis } catch (err) { catchErr(err, message) } })
方案2:修改命令处理器,全局统一捕获所有命令的执行错误
不需要每个命令都重复写try/catch,直接修改你的basic-command-handler.js文件,找到执行命令回调的对应位置(对应报错栈里的basic-command-handler.js:21:11行),在执行回调的外层包裹错误捕获:
// 原逻辑大概如下,找到你执行命令回调的代码 // commandCallback(message, args) // 修改为 try { commandCallback(message, args) } catch (err) { // 直接调用你写好的catchErr函数,或者在这里写错误通知逻辑 catchErr(err, message) }
方案3:添加全局异常捕获,兜底处理所有未被捕获的错误
为了避免还有漏网的错误导致进程直接崩溃,在入口文件最顶部添加全局异常监听逻辑:
// 捕获同步未处理异常 process.on('uncaughtException', (err) => { console.error('未捕获的全局异常:', err) const owner = client.users.cache.get("762267309661356042") if (owner) { owner.send(`全局未捕获异常:\`\`\`js\n${err.stack}\n\`\`\``).catch(() => {}) } // 出现uncaughtException后进程状态已经不稳定,建议用pm2等进程守护工具自动重启 }) // 捕获异步Promise未处理的拒绝错误 process.on('unhandledRejection', (reason) => { console.error('未处理的Promise错误:', reason) const owner = client.users.cache.get("762267309661356042") if (owner) { owner.send(`全局异步错误:\`\`\`js\n${reason.stack || reason}\n\`\`\``).catch(() => {}) } }) // 监听discord.js客户端本身抛出的错误 client.on('error', (err) => { console.error('客户端错误:', err) const owner = client.users.cache.get("762267309661356042") if (owner) { owner.send(`客户端错误:\`\`\`js\n${err.stack}\n\`\`\``).catch(() => {}) } })
优化建议
你原有的catchErr函数可以优化一下,避免发送通知失败时抛出新的错误:
function catchErr (err, message) { const owner = client.users.cache.get("762267309661356042") if (!owner) return console.error('找不到所有者用户,错误详情:', err) // 打印完整错误栈方便排查问题,不要只打印err本身 owner.send(`错误触发位置:频道 ${message.channel},服务器 ${message.guild || "私信场景"}`) .then(() => owner.send(`错误详情:\`\`\`js\n${err.stack}\n\`\`\``)) .catch(sendErr => console.error('发送错误通知失败:', sendErr)) }
内容的提问来源于stack exchange,提问作者Zanci19
相关产品推荐
相关产品推荐

