Discord.js机器人upload命令报错排查与功能实现求助
问题分析与修复方案
我来帮你搞定这个问题!先拆解下你遇到的核心问题:
- 报错
Cannot read property 'first' of undefined:根源是awaitMessages返回的是消息集合(MessageCollection),你直接在这个集合上访问attachments肯定会返回undefined,得先取出集合里的具体消息才行。 - 未处理Promise拒绝警告:因为你没有处理
awaitMessages可能出现的超时、用户未发送消息等异常情况,这些都会触发Promise拒绝,Node.js已经明确提示未来这种情况会直接终止进程,必须处理。
另外还有个隐藏问题:你写的文件路径./MusicFiles是文件夹,直接用createWriteStream指向文件夹会报错,得加上具体的文件名(从附件里获取)。
修复后的完整代码
const { MessageEmbed } = require(`discord.js`); const fs = require('fs'); const request = require(`request`); // 确保保存文件夹存在,不存在则自动创建 fs.mkdirSync('./MusicFiles', { recursive: true }); module.exports = { name: 'upload', description: 'command used to upload .mp3 file', async execute(message, args){ const HelpEmbed = new MessageEmbed() .setTitle('Test') .setColor(0xff0000) .setDescription('请上传你的.mp3文件,我会帮你保存下来!'); await message.channel.send(HelpEmbed); try { // 等待用户发送消息,返回的是MessageCollection类型 const messageCollection = await message.channel.awaitMessages( m => m.author.id === message.author.id, { max: 1, time: 300000, errors: ['time'] } ); // 从集合中取出用户发送的那条具体消息 const userMessage = messageCollection.first(); // 检查消息是否包含附件 if (!userMessage.attachments.size) { return message.channel.send('你没有上传任何附件哦,请重新发送!'); } // 获取第一个附件对象 const attachment = userMessage.attachments.first(); // 可选:校验文件格式是否为mp3 if (!attachment.name.endsWith('.mp3')) { return message.channel.send('请上传.mp3格式的文件!'); } // 拼接完整保存路径:文件夹 + 附件原名 const savePath = `./MusicFiles/${attachment.name}`; // 下载并保存文件 request.get(attachment.url) .on('error', (err) => { console.error('文件下载出错:', err); message.channel.send('文件下载失败,请稍后重试!'); }) .pipe(fs.createWriteStream(savePath)) .on('finish', () => { message.channel.send(`文件已成功保存到:${savePath}`); }); } catch (err) { // 处理超时或其他异常情况 if (err.message.includes('time')) { return message.channel.send('时间到了,你没有上传文件,命令已取消!'); } console.error('命令执行出错:', err); message.channel.send('命令执行出错,请稍后重试!'); } } }
关键改动说明
- 用
try/catch包裹所有异步操作,处理超时和其他异常,彻底解决未处理Promise拒绝的问题。 - 正确从
awaitMessages返回的集合中取出用户消息:messageCollection.first(),再访问其attachments属性。 - 增加了附件存在性校验,以及可选的.mp3格式校验,提升用户体验。
- 自动创建
./MusicFiles文件夹(避免因文件夹不存在导致的报错),并使用附件原名保存文件。 - 增加了下载完成、出错的用户提示,让操作结果更清晰。
内容的提问来源于stack exchange,提问作者user14247741
相关产品推荐
相关产品推荐

