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

Discord.js机器人!am命令报错:TypeError: Cannot read properties of null (reading 'save')

Discord.js机器人执行!am命令时出现Cannot read properties of null (reading 'save')错误

问题原因

错误出在channel.save()调用时,channel为null,这是因为channelModel.findOne({channelId: message.channel.id})在数据库中找不到对应频道的记录。通常发生在第一次在目标频道使用该命令时,数据库还未创建该频道的文档。

解决方案

有两种可行的修复方式,根据你的需求选择:

方案1:使用findOneAndUpdate自动创建文档(推荐)

利用MongoDB的findOneAndUpdate方法,结合upsert: true选项,实现"找不到就创建,找到就更新"的逻辑,同时用$addToSet自动避免重复添加用户ID:

const channelModel = require("../models/channel.model");

module.exports = {
  name: "am",
  usage: "@<user> @<optional_user> ...",
  guildOnly: true,
  description: "Adds a new member to the standup",
  async execute(message, args) {
    if (!args.length)
      return message.channel.send(
        "Ruh Roh! You need to mention **_at least_** one member as argument!"
      );

    // 提取所有有效用户ID
    const memberIds = [];
    args.forEach((mention) => {
      if (mention.startsWith("<@") && mention.endsWith(">")) {
        let userId = mention.slice(2, -1);
        if (userId.startsWith("!")) userId = userId.slice(1);
        const member = message.guild.members.cache.get(userId);
        if (member) memberIds.push(member.id);
      }
    });

    if (memberIds.length === 0) {
      return message.channel.send("No valid members mentioned!");
    }

    try {
      // 查找或创建频道文档,并添加用户ID(自动去重)
      await channelModel.findOneAndUpdate(
        { channelId: message.channel.id },
        { 
          serverId: message.guild.id,
          $addToSet: { members: { $each: memberIds } }
        },
        { upsert: true, new: true }
      );
      message.channel.send("Members updated :tada:");
    } catch (err) {
      console.error(err);
      message.channel.send(
        "Oh no :scream:! An error occured somewhere in the matrix!"
      );
    }
  },
};

方案2:手动判断并创建新文档

先检查查询结果是否为null,如果是则手动创建新的Channel实例,再进行后续操作:

const channelModel = require("../models/channel.model");

module.exports = {
  name: "am",
  usage: "@<user> @<optional_user> ...",
  guildOnly: true,
  description: "Adds a new member to the standup",
  async execute(message, args) {
    if (!args.length)
      return message.channel.send(
        "Ruh Roh! You need to mention **_at least_** one member as argument!"
      );

    // 查找频道文档
    let channel = await channelModel.findOne({ channelId: message.channel.id });

    // 如果不存在,创建新文档
    if (!channel) {
      channel = new channelModel({
        serverId: message.guild.id,
        channelId: message.channel.id,
        members: []
      });
    }

    // 处理用户提及
    args.forEach((mention) => {
      if (mention.startsWith("<@") && mention.endsWith(">")) {
        let userId = mention.slice(2, -1);
        if (userId.startsWith("!")) userId = userId.slice(1);
        const member = message.guild.members.cache.get(userId);

        if (member && channel.members.indexOf(member.id) === -1) {
          channel.members.push(member.id);
        }
      }
    });

    try {
      await channel.save();
      message.channel.send("Members updated :tada:");
    } catch (err) {
      console.error(err); // 修正原代码中的console.err拼写错误
      message.channel.send(
        "Oh no :scream:! An error occured somewhere in the matrix!"
      );
    }
  },
};

额外注意点

  • 原代码中存在拼写错误:console.err应该改为console.error,已在方案2中修正。
  • 使用async/await替代嵌套的.then()语法,让代码结构更清晰易读。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:51:13