如何修复Discord.js自定义前缀功能的Cannot set properties of undefined错误
问题修复方案
报错根因
- 首次运行未初始化过前缀配置时,
keyv.get('prefix')返回undefined,直接对undefined设置属性触发类型错误 - 原存储逻辑错误使用字符串模板拼接对象,会将对象转为
[object Object]无效字符串,下次读取到的内容无法作为对象操作
修复后的完整代码
const { Client, Intents, MessageEmbed } = require('discord.js'); let client = new Client({ intents: [Intents.FLAGS.GUILDS,Intents.FLAGS.GUILD_MESSAGES] }); const dotenv = require('dotenv'); const Keyv = require('keyv'); const keyv = new Keyv(); dotenv.config(); client.on('ready', () => { console.log(`Logged in as ${client.user.tag}!`); }); client.on('messageCreate', async (msg) => { // 忽略机器人消息、非服务器私信消息 if (msg.author.bot || !msg.guild) return; let number = msg.content.split(' ')[1]; if (msg.content === '!ping') { msg.channel.send('ping!') } const getGuildPrefix = async () => { const prefixMap = await keyv.get('prefix') || {}; return prefixMap[msg.guild.id] || "!" } // 为当前服务器设置前缀 const setGuildPrefix = async (prefix) => { // 读取不到配置默认初始化为空对象 const prefixMap = await keyv.get('prefix') || {}; prefixMap[msg.guild.id] = prefix; // 直接传入对象存储,Keyv会自动序列化处理,无需手动转字符串 await keyv.set('prefix', prefixMap); } let prefix = await getGuildPrefix(); // 获取前缀命令 if ((msg.content === `${process.env.prefix}prefix`) || (msg.content === `${prefix}prefix`)) { msg.channel.send(`Your server prefix is ${prefix}`) } // 可选:补全设置前缀的调用逻辑,示例仅允许管理员修改前缀 if (msg.content.startsWith(`${prefix}setprefix`) && msg.member.permissions.has('ADMINISTRATOR')) { const newPrefix = msg.content.split(' ')[1]; if (!newPrefix) return msg.channel.send('请输入新的前缀'); await setGuildPrefix(newPrefix); msg.channel.send(`已将服务器前缀修改为 ${newPrefix}`); } }) client.login(process.env.token);
核心修改点
- 读取
prefix配置时新增兜底逻辑,空值默认返回空对象{},避免操作undefined的报错 - 存储时直接传入对象参数,不要手动转字符串
- 新增消息过滤逻辑,忽略机器人消息和私信消息,避免
msg.guild为undefined的额外报错 - 补全原代码缺失的
setGuildPrefix调用入口,可根据需求调整权限控制逻辑
内容的提问来源于stack exchange,提问作者Amrit R Asher
相关产品推荐
相关产品推荐

