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

Discord.js v12.5.3 mention prefix功能触发Cannot read property '0'报错求助

问题排查与修复方案

错误原因

你收到的报错:

(node:19812) UnhandledPromiseRejectionWarning: TypeError: Cannot read property '0' of null

触发根源是String.prototype.match()在没有匹配到结果时会返回null,你的代码没有做空值判断就直接访问mentionPrefix[0],当用户使用普通前缀(比如s!help)发命令、没有@机器人时,就会抛出这个类型错误。

现存逻辑问题

  • 前缀赋值逻辑错误:&&运算符的特性会让你写的prefix = "s!" && mentionPrefix[0]强制取后面的mentionPrefix[0]值,普通前缀完全失效,同时空值访问直接触发报错
  • 无空值校验:所有调用mentionPrefix[0]的位置都没有提前判断匹配是否成功
  • 前缀匹配逻辑错误:你需要的是「普通前缀/提及前缀二选一匹配」,而非同时满足两个条件

修复后完整代码

const {MessageEmbed} = require('discord.js')
const client = require('../index')
const db = require('quick.db')
const dbx = require('xen.db')


client.on('message', async (message) => {
    if(message.author.bot || message.channel.type === "dm") return;
    let prefix;
    // 优先取自定义前缀,没有就用默认s!
    let prefixess = await db.fetch(`simply_prefix_${message.guild.id}`) || "s!"

    const mentionPrefix = message.content.match(new RegExp(`^<@!?(${client.user.id})>`,'gi'))

    // 前缀判断:优先匹配提及前缀,匹配不到用普通前缀
    if(mentionPrefix && mentionPrefix.length){
        prefix = mentionPrefix[0]
        // 单独@机器人直接返回前缀提示
        if(message.content.trim() === prefix){
            const pingEmbed = new MessageEmbed()
            .setColor('YELLOW')
            .setDescription(`本服务器的命令前缀是:\`${prefixess} || @SimplyBot\`\n查看命令列表请发送:\`${prefixess}help\` 或 \`@SimplyBot help\`!`)
            return message.channel.send(pingEmbed)
        }
    }else{
        prefix = prefixess
    }

    const messageArray = message.content.split(' ');
    const cmd = messageArray[0];
    const args = messageArray.slice(1);

    if (!message.content.startsWith(prefix)) return;
    const commandfile = client.commands.get(cmd.slice(prefix.length).trim()) || client.commands.get(client.aliases.get(cmd.slice(prefix.length).trim()));

    
    if(commandfile){
        if(commandfile.config.premium){
            if(commandfile.config.premium === true){
                const premium = dbx.fetch(`simply_premium`) || []
                const expiry = dbx.fetch(`simply_premium_date_${message.guild.id}`)
     
                if(!premium.includes(message.guild.id)){
                    return message.reply(`这是高级版专属命令,你无权使用`)
                } 
                if(expiry && Date.now() > expiry) {
                    dbx.pull(`simply_premium`, message.guild.id)
                    dbx.set(`simply_premium_date_${message.guild.id}`, 0)
                    return message.reply(`你的服务器高级版已过期`)
                }
                commandfile.run(client, message, args, dbx, db)
            }
        } else {
            commandfile.run(client, message, args, dbx, db)
        }
    }
})

额外优化说明

  • 修正了高级版权限判断的逻辑顺序,避免高级版过期后还能执行一次命令的漏洞
  • 修正了includes调用顺序,避免数组为空时报错
  • 给命令名匹配加了trim处理,避免多余空格导致匹配失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 15:30:03