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

使用Discord.js+MongoDB开发定时器命令遇BSONTypeError求助

问题:Agenda执行任务时触发BSON BigInt不支持错误

我使用Discord.js、MongoDB(mongoose封装)和Agenda开发定时器命令,功能是在指定时间后自动从数据库删除定时器。Bot就绪后会遍历数据库中的定时器,根据时间判断执行或推迟Agenda任务。但执行agenda.now<RemoveTimer>后代码停止运行,Agenda定义的任务从未执行,且出现报错:BSONTypeError: Unsupported type BigInt, please use Decimal128。

相关代码片段

遍历定时器并触发Agenda任务

// models.timer为mongoose的Model实例
const timers = await models.timer.find();
for (const timer of timers) {
  if (Date.now() > timer.endsAt) {
    console.log(Date.now(), timer.endsAt, timer.id); // 此日志正常输出
    await agenda.now<RemoveTimer>(AgendaJobs.RemoveTimer, {
      timerId: timer.id,
      client: this.container.client,
    });
    console.log("done"); // 从未输出
  }
}

Agenda任务定义

agenda.define<RemoveTimer>(
  AgendaJobs.RemoveTimer,
  async (job: Job<RemoveTimer>) => {
    console.log("job"); // 从未输出
    // ... 任务逻辑
  }
);

Mongoose Timer Schema

const schema = new Schema<ITimer>({
  name: {
    type: String,
    default: "Timer",
  },
  createdBy: String,
  channelId: String,
  endsAt: Number,
  dm: {
    type: Boolean,
    default: false,
  },
});
export const TimerModel = model<ITimer>("timer", schema);

完整报错信息

2024-08-07 19:58:26 - ERROR - Encountered error on event listener "ready" for event "ready" at path "H:\GitStuff\nightmare-utils\dist\listeners\ready.js" BSONTypeError: Unsupported type BigInt, please use Decimal128
2024-08-07 19:58:26 - ERROR -     at new BSONTypeError (H:\GitStuff\nightmare-utils\node_modules\mongodb\node_modules\bson\lib\error.js:41:28)
2024-08-07 19:58:26 - ERROR -     at serializeInto (H:\GitStuff\nightmare-utils\node_modules\mongodb\node_modules\bson\lib\parser\serializer.js:788:35)
2024-08-07 19:58:26 - ERROR -     at serializeObject (H:\GitStuff\nightmare-utils\node_modules\mongodb\node_modules\bson\lib\parser\serializer.js:282:20)
2024-08-07 19:58:26 - ERROR -     at serializeInto (H:\GitStuff\nightmare-utils\node_modules\mongodb\node_modules\bson\lib\parser\serializer.js:813:25)
2024-08-07 19:58:26 - ERROR -     at serializeObject (H:\GitStuff\nightmare-utils\node_modules\mongodb\node_modules\bson\lib\parser\serializer.js:282:20)
2024-08-07 19:58:26 - ERROR -     at serializeInto (H:\GitStuff\nightmare-utils\node_modules\mongodb\node_modules\bson\lib\parser\serializer.js:813:25)
2024-08-07 19:58:26 - ERROR -     at serializeObject (H:\GitStuff\nightmare-utils\node_modules\mongodb\node_modules\bson\lib\parser\serializer.js:282:20)
2024-08-07 19:58:26 - ERROR -     at serializeInto (H:\GitStuff\nightmare-utils\node_modules\mongodb\node_modules\bson\lib\parser\serializer.js:813:25)
2024-08-07 19:58:26 - ERROR -     at serializeObject (H:\GitStuff\nightmare-utils\node_modules\mongodb\node_modules\bson\lib\parser\serializer.js:282:20)
2024-08-07 19:58:26 - ERROR -     at serializeInto (H:\GitStuff\nightmare-utils\node_modules\mongodb\node_modules\bson\lib\parser\serializer.js:607:25) {
2024-08-07 19:58:26 - ERROR -   originalLine: 45,
2024-08-07 19:58:26 - ERROR -   originalColumn: 30
2024-08-07 19:58:26 - ERROR - }

解决方案

核心原因

传给Agenda任务的client参数是Discord.js的Client实例,其中包含大量BigInt类型的字段(比如各种ID),而Agenda会将任务参数序列化为BSON存储到MongoDB中,BSON不支持直接序列化BigInt类型,导致序列化失败,代码中断,因此后续的日志和任务都无法执行。

修复步骤

  1. 避免传递复杂对象:不要将整个Discord.js Client实例传给Agenda任务,任务中如果需要使用Client,可以直接引用全局的Bot实例,无需通过参数传递。
  2. 转换BigInt为字符串:如果需要传递ID类参数(比如timer.id),将BigInt类型转换为字符串,Discord.js完全支持用字符串ID进行操作:
    await agenda.now<RemoveTimer>(AgendaJobs.RemoveTimer, {
      timerId: String(timer.id), // 将BigInt转为字符串
      // 移除client参数
    });
    
  3. 精简任务参数:只传递任务执行必需的最小化参数(比如需要发送消息的话,只传channelId、userId等字符串类型参数),不要传递包含复杂类型的对象。

验证修改

修改后,Agenda任务参数可以正常序列化为BSON,代码会继续执行到"done"日志,Agenda的任务也会正常触发执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 22:07:34