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

Discord.js机器人闲置30分钟后触发DiscordAPIError[10062]崩溃

解决Discord.js机器人闲置后触发DiscordAPIError[10062]的问题

问题描述

我的Discord.js机器人所有命令、交互功能初始运行均正常,但将其在线闲置30分钟后,再次执行命令时会触发如下DiscordAPIError[10062]错误并崩溃:

/home/yetnt/bots/mJb/node_modules/@discordjs/rest/dist/index.js:640
      throw new DiscordAPIError(data, "code" in data ? data.code : data.error, status, method, url, requestData);
            ^

DiscordAPIError[10062]: Unknown interaction
    at handleErrors (/home/yetnt/bots/mJb/node_modules/@discordjs/rest/dist/index.js:640:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async BurstHandler.runRequest (/home/yetnt/bots/mJb/node_modules/@discordjs/rest/dist/index.js:736:23)
    at async REST.request (/home/yetnt/bots/mJb/node_modules/@discordjs/rest/dist/index.js:1387:22)
    at async ChatInputCommandInteraction.deferReply (/home/yetnt/bots/mJb/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:69:5) {
  requestBody: { files: undefined, json: { type: 5, data: { flags: undefined } } },
  rawError: { message: 'Unknown interaction', code: 10062 },
  code: 10062,
  status: 404,
  method: 'POST',
  url: 'https://discord.com/api/v10/interactions/1107289296546832485/aW50ZXJhY3Rpb246MTEwNzI4OTI5NjU0NjgzMjQ4NTpNcmhrYWh0ZGdndzQ5SjJWT3BEYWNhWDNsMHIwT2YwaWxlVFMyclByd2ZuNWpLejNPSmEyOG14T3kwOXNZc3l5VnFHTkgwVUhKYW55Q0RmajlXb1NoSDgzUnNYN1pKZEFzNU9LR3puaFZKVm1XbjZJRHZydkVZTEpNcnRSUHBIdA/callback'
}

Node.js v18.16.0
[nodemon] app crashed - waiting for file changes before starting...

重启机器人后功能恢复正常,但再次闲置后问题复现。

核心原因

  • Discord交互令牌的有效期仅为15分钟,机器人闲置后首次执行命令时,数据库查询(如User/Inventory/Cooldown模型查询)因连接休眠、无索引等原因耗时过长,导致超过令牌有效期才调用interaction.deferReply(),Discord已不再识别该交互。
  • 未针对10062错误做捕获处理,导致错误直接崩溃机器人进程。

解决方案

1. 优先响应交互,再处理耗时逻辑

Discord要求必须在3秒内对交互做出响应(包括延迟回复),需将deferReply放在所有耗时操作最前端,避免超时:

// 修改rob.js的callback函数
callback: async (client, interaction) => {
    // 先立即执行延迟回复,确保在3秒内响应Discord
    const deferSuccess = await interaction.deferReply().catch(err => {
        console.error("延迟回复失败:", err);
        return false;
    });
    if (!deferSuccess) return;

    try {
        // 所有数据库查询和业务逻辑放在这里
        let victimId = interaction.options.get("victim").value
        const sf = rndInt(1, 2) // 2 = success; 1 = failure

        let victim = await User.findOne({userId: victimId})
        // ... 剩余原有业务逻辑
    } catch (error) {
        // 判断交互状态后再发送错误提示
        if (interaction.deferred) {
            await interaction.editReply('操作出错了').catch(() => {});
        }
        // ... 原有错误日志逻辑
    }
}

2. 优化数据库连接,防止闲置断开

如果使用MongoDB/Mongoose,添加连接保活配置,避免闲置时连接被断开:

// 数据库连接代码中添加以下配置
mongoose.connect(process.env.MONGO_URI, {
    keepAlive: true,
    keepAliveInitialDelay: 300000, // 5分钟保活心跳
    connectTimeoutMS: 10000,
    socketTimeoutMS: 45000
});

3. 捕获10062错误,避免机器人崩溃

在命令处理的全局catch块和命令内部catch块中,专门捕获该错误:

// 修改handleCommands.js的catch块
catch (error) {
    if (error.code === 10062) {
        console.log("交互已过期:用户在令牌失效后执行命令");
        return;
    }
    console.log(`执行命令时出错:`);
    console.log(error)
}

// 修改rob.js的catch块
catch (error) {
    if (error.code === 10062) {
        console.log(`命令${interaction.commandName}的交互已过期,用户ID:${interaction.user.id}`);
        return;
    }
    // ... 原有错误回复和日志逻辑
}

4. 添加数据库索引,加快查询速度

给User/Inventory/Cooldown模型的userId字段添加索引,大幅减少查询耗时:

// User模型示例
const UserSchema = new mongoose.Schema({
    userId: { type: String, index: true }, // 添加索引
    balance: Number,
    // ... 其他字段
});
// Inventory和Cooldown模型同理添加userId索引

验证效果

修改完成后,让机器人闲置超过30分钟再执行命令,将不会触发Unknown interaction错误,且机器人不会崩溃。提前执行的deferReply会刷新交互令牌有效期,后续编辑回复操作可正常进行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:27:35