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

Discord.js机器人频繁触发HTTPError 500问题求助

Discord.js机器人频繁因HTTPError 500崩溃的问题

我为朋友运行两个Discord.js机器人已有数年,分别部署在2个和12个服务器中,此前一直运行正常。但自2022年9月24日起,机器人每日约8次因如下报错崩溃:

发送消息时的报错

HTTPError [AbortError]: The user aborted a request.
    at RequestHandler.execute (/root/node_modules/discord.js/src/rest/RequestHandler.js:201:15)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async RequestHandler.push (/root/node_modules/discord.js/src/rest/RequestHandler.js:51:14)
    at async TextChannel.send (/root/node_modules/discord.js/src/structures/interfaces/TextBasedChannel.js:175:15) {
  code: 500,
  method: 'post',
  path: '/channels/[channel id here]/messages',
  requestData: {
    json: {
      content: '[message content here]',
      tts: false,
      nonce: undefined,
      embeds: undefined,
      components: undefined,
      username: undefined,
      avatar_url: undefined,
      allowed_mentions: undefined,
      flags: undefined,
      message_reference: undefined,
      attachments: undefined,
      sticker_ids: undefined
    },
    files: []
  }
}
/root/node_modules/discord.js/src/rest/RequestHandler.js:201
        throw new HTTPError(error.message, error.constructor.name, error.status, request);
              ^

删除消息时的报错

HTTPError [AbortError]: The user aborted a request.
    at RequestHandler.execute (/root/node_modules/discord.js/src/rest/RequestHandler.js:201:15)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async RequestHandler.push (/root/node_modules/discord.js/src/rest/RequestHandler.js:51:14)
    at async MessageManager.delete (/root/node_modules/discord.js/src/managers/MessageManager.js:210:5)
    at async Message.delete (/root/node_modules/discord.js/src/structures/Message.js:792:5) {
  code: 500,
  method: 'delete',
  path: '/channels/[channel id here]/messages/[message id here]',
  requestData: { json: undefined, files: [] }
}
/root/node_modules/discord.js/src/rest/RequestHandler.js:201
        throw new HTTPError(error.message, error.constructor.name, error.status, request);
              ^

我已通过forever工具在机器人崩溃时自动重启,但重启需数分钟,期间机器人处于不可用状态。我了解Discord已切换至slash commands,但该要求仅针对服务器数量>75的机器人,我的机器人不符合该条件,且问题突发前未对机器人做任何修改。我曾看到相关回答建议捕获并忽略HTTPErrors,但这会导致当前消息发送/删除操作失败。现请教两个问题:

  1. HTTPError 500是否有易规避的原因?为何此前多年无问题,如今每日因API超时多次触发?
  2. 若捕获该错误,是否可以重试请求?有无简便实现方式?我设想将消息发送/删除逻辑重构为带try-catch的单函数,在catch块中重试,该方案是否可行?

问题解答

1. HTTPError 500的触发原因与规避思路

Discord的500错误属于服务器端内部错误,和你的机器人代码、配置无关。突然出现这类问题的常见原因:

  • Discord API节点临时波动或集群负载过高,导致请求处理超时或失败
  • 删除消息的操作涉及多节点状态同步,在Discord端链路更长,高负载下更容易触发内部错误
  • 尽管你的机器人服务器数量未达强制切换slash commands的门槛,但Discord可能在逐步调整旧消息接口的资源优先级,导致稳定性下降

这类错误没有绝对的“规避”方法,但可以通过以下方式降低触发概率:

  • 确保你的Discord.js版本是最新稳定版,新版本通常会修复API请求的兼容性问题
  • 避免短时间内批量发送/删除消息,给API请求留足间隔

2. 重试请求的可行性与实现方案

捕获错误后重试请求完全可行,你设想的try-catch封装方案是最直接有效的实现方式。

具体实现思路

封装一个通用的重试函数,将发送/删除消息的异步操作作为参数传入,捕获到500错误时自动重试,同时设置最大重试次数和重试间隔,避免无限循环或加重API负载。

示例代码

const { HTTPError } = require('discord.js');

// 通用重试函数
async function withRetry(asyncOperation, maxRetries = 3, retryDelay = 1000) {
  let attemptCount = 0;
  while (attemptCount < maxRetries) {
    try {
      return await asyncOperation();
    } catch (err) {
      attemptCount++;
      // 仅对500类型的HTTPError重试
      if (!(err instanceof HTTPError) || err.code !== 500) {
        throw err;
      }
      // 等待指定间隔后重试
      await new Promise(resolve => setTimeout(resolve, retryDelay));
    }
  }
  throw new Error(`操作失败:已重试${maxRetries}次仍未成功`);
}

// 使用示例:发送消息
await withRetry(() => yourChannel.send('测试消息'));

// 使用示例:删除消息
await withRetry(() => targetMessage.delete());

注意事项

  • 重试间隔建议设置在1-3秒,过短的间隔可能触发Discord的限流机制
  • 删除消息属于幂等操作,重试不会产生副作用;发送消息如果需要避免重复,可添加nonce参数保证消息唯一性
  • 不要忘记捕获最终重试失败的情况,根据业务需求做降级处理(比如记录日志)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 22:21:39