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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:37:29