Discord音乐机器人非法链接崩溃,catch失效及链接校验需求
问题修复方案
核心问题分析
- try-catch未生效:
client.distube.play是异步方法,原代码未用await等待其执行完成,导致异步错误无法被外层try-catch捕获;同时catch块中引用了未定义的but变量,会引发二次错误。 - 选项名不匹配:命令定义的参数名是
song,但代码中用options.getString("трек")获取值,导致query为undefined,触发异常。 - 缺少链接预校验:未在调用播放接口前校验链接有效性,非法链接直接触发DisTube内部抛出的未捕获错误。
修复步骤
1. 修正参数获取错误
将获取歌曲参数的代码改为对应命令定义的名称:
const query = options.getString("song");
2. 提前校验链接有效性
使用DisTube内置方法提前校验链接,非法链接直接返回错误提示:
// 校验链接是否为不支持的格式 if (client.distube.isValidURL(query)) { try { await client.distube.resolve(query); } catch (resolveErr) { if (resolveErr.errorCode === "NOT_SUPPORTED_URL") { const errEmbed = new EmbedBuilder() .setColor("Red") .setDescription(`❌ 不支持的链接格式,请输入有效的音乐平台链接或歌曲名称!`); return interaction.reply({ embeds: [errEmbed], ephemeral: true }); } } }
3. 修复try-catch捕获逻辑
给distube.play添加await确保异步错误能被捕获,同时移除未定义的组件参数:
try { await client.distube.play(voiceChannel, query, { textChannel: channel, member: member }); return interaction.reply({ content: `🎶 正在查找曲目 \`${query}\`...`, ephemeral: true }); } catch (err) { console.error(err); const errEmbed = new EmbedBuilder() .setColor("Red") .setDescription(`❌ 操作失败:\`${err.message || err}\``); return interaction.reply({ embeds: [errEmbed], ephemeral: true }); }
4. 优化数据库查询写法(可选)
将回调式查询改为async/await,提升代码可读性与错误捕获能力:
const data = await Schema.findOne({ Guild: member.guild.id }); if (!data) { const embed = new EmbedBuilder() .setColor("Red") .setDescription(`未配置音乐频道!请使用 \`/music setup\` 命令配置,或联系管理员。`); return interaction.reply({ embeds: [embed], ephemeral: true }); }
完整修复代码
const { EmbedBuilder, SlashCommandBuilder } = require("discord.js"); const client = require("../../index"); const Schema = require("../../Models/Music"); module.exports = { data: new SlashCommandBuilder() .setName("play") .setDescription("播放歌曲") .addStringOption(option => option.setName("song") .setDescription("提供歌曲链接或名称") .setRequired(true) ), async execute(interaction) { const { options, member, guild, channel } = interaction; // 异步查询音乐频道配置 const data = await Schema.findOne({ Guild: member.guild.id }); if (!data) { const embed = new EmbedBuilder() .setColor("Red") .setDescription(`未配置音乐频道!请使用 \`/music setup\` 命令配置,或联系管理员。`); return interaction.reply({ embeds: [embed], ephemeral: true }); } const query = options.getString("song"); const voiceChannel = member.voice.channel; const musicVoiceChannel = member.guild.channels.cache.get(data.Channel); const musicTextChannel = member.guild.channels.cache.get(data.TextChannel); const embed = new EmbedBuilder(); // 校验命令使用频道 if (channel !== musicTextChannel) { embed.setColor("Red").setDescription(`音乐命令仅能在 ${musicTextChannel} 频道使用!`); return interaction.reply({ embeds: [embed], ephemeral: true }); } // 校验语音频道 if (!voiceChannel || voiceChannel !== musicVoiceChannel) { embed.setColor("Red").setDescription(`你必须连接到语音频道 ${musicVoiceChannel} 才能执行音乐命令!`); return interaction.reply({ embeds: [embed], ephemeral: true }); } // 校验机器人是否已在其他频道运行 if (guild.members.me.voice.channelId && member.voice.channelId !== guild.members.me.voice.channelId) { embed.setColor("Red").setDescription(`音乐播放器已在 <#${guild.members.me.voice.channelId}> 频道运行,无法在此使用!`); return interaction.reply({ embeds: [embed], ephemeral: true }); } // 预校验链接有效性 if (client.distube.isValidURL(query)) { try { await client.distube.resolve(query); } catch (resolveErr) { if (resolveErr.errorCode === "NOT_SUPPORTED_URL") { const errEmbed = new EmbedBuilder() .setColor("Red") .setDescription(`❌ 不支持的链接格式,请输入有效的音乐平台链接或歌曲名称!`); return interaction.reply({ embeds: [errEmbed], ephemeral: true }); } } } // 执行播放逻辑 try { await client.distube.play(voiceChannel, query, { textChannel: channel, member: member }); return interaction.reply({ content: `🎶 正在查找曲目 \`${query}\`...`, ephemeral: true }); } catch (err) { console.error(err); const errEmbed = new EmbedBuilder() .setColor("Red") .setDescription(`❌ 操作失败:\`${err.message || err}\``); return interaction.reply({ embeds: [errEmbed], ephemeral: true }); } } };
内容的提问来源于stack exchange,提问作者Drif
相关产品推荐
相关产品推荐

