You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Discord.js中实现顶层错误处理?

解决Discord.js机器人顶层错误处理问题

问题原因

你当前的.catch未触发,是因为测试命令里的interaction.reply是异步方法,但未使用await,导致该异步操作的错误未被包含在commandFile.run返回的Promise中,成为未捕获的Promise拒绝,无法被外层.catch捕获。

解决方案

1. 全局错误监听(防止机器人崩溃)

在机器人启动代码中添加全局错误监听,捕获所有未处理的异常和Promise拒绝,避免机器人意外崩溃:

// 捕获未处理的Promise拒绝
process.on('unhandledRejection', async (reason, promise) => {
  console.error('未处理Promise拒绝:', reason);
  // 发送错误到指定日志频道
  const logChannel = client.channels.cache.get('你的日志频道ID');
  if (logChannel) {
    await logChannel.send({
      content: `⚠️ 未处理Promise拒绝:\n\`\`\`${reason.stack || reason}\`\`\``
    }).catch(err => console.error('发送日志失败:', err));
  }
});

// 捕获未捕获的同步异常
process.on('uncaughtException', async (err) => {
  console.error('未捕获异常:', err);
  const logChannel = client.channels.cache.get('你的日志频道ID');
  if (logChannel) {
    await logChannel.send({
      content: `❌ 未捕获异常:\n\`\`\`${err.stack || err}\`\`\``
    }).catch(err => console.error('发送日志失败:', err));
  }
});

2. 命令处理器层通用错误处理(无需修改底层命令)

修改interactionCreate事件逻辑,用try/catch包裹整个命令执行流程,同时给用户反馈并记录错误日志:

client.on('interactionCreate', async interaction => {
  try {
    if (interaction.isChatInputCommand()) {
      let args = [];
      for (let i = 0; i < interaction.options._hoistedOptions.length; i++) {
        args.push({
          name: interaction.options._hoistedOptions[i].name,
          value: interaction.options._hoistedOptions[i].value
        });
      }

      const commandFile = client.commands.get(interaction.commandName);
      if (commandFile) {
        await commandFile.run(client, interaction, args, DefaultFooter, LocalMap);
      }
      console.log(`${interaction.member ? interaction.member.user.tag : interaction.user.tag} executed command (Slash): ${interaction.commandName}`);
    }

    if (interaction.isContextMenuCommand()) {
      const commandFile = client.commands.get(interaction.commandName);
      if (commandFile) {
        await commandFile.run(client, interaction, DefaultFooter, LocalMap);
      }
      console.log(`${interaction.member ? interaction.member.user.tag : interaction.user.tag} executed command (Context): ${interaction.commandName}`);
    }
  } catch (err) {
    console.error('命令执行错误:', err);
    // 给用户发送错误提示(仅用户可见)
    if (!interaction.replied && !interaction.deferred) {
      await interaction.reply({
        content: '执行命令时发生错误,请联系管理员。',
        ephemeral: true
      }).catch(() => {});
    } else {
      await interaction.followUp({
        content: '执行命令时发生错误,请联系管理员。',
        ephemeral: true
      }).catch(() => {});
    }
    // 发送详细错误到日志频道
    const logChannel = client.channels.cache.get('你的日志频道ID');
    if (logChannel) {
      await logChannel.send({
        content: `❌ 命令执行错误\n**用户**: ${interaction.user.tag}\n**命令**: ${interaction.commandName}\n\`\`\`${err.stack || err}\`\`\``
      }).catch(err => console.error('发送日志失败:', err));
    }
  }
});

3. 补充说明

  • 若无法修改底层命令文件,全局unhandledRejection监听是必要的,可捕获命令内部未用await的异步操作错误。
  • 建议尽量让所有命令中的异步方法都添加await,这样错误能被顶层try/catch直接捕获,处理更及时。
  • 需将代码中的你的日志频道ID替换为实际的日志频道ID。

内容的提问来源于stack exchange,提问作者Bobosky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 10:32:46