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

如何修复Node.js中的Unhandled Promise Rejection问题?

解决Unhandled Promise Rejection错误及你的Discord Bot代码问题

嘿,咱先把这个Unhandled Promise Rejection的问题给你捋明白,再一步步修复你的代码:

首先,你的错误根源有这么几个:

  • 你在自执行的async函数里直接写了throw(),而且这个函数没有任何错误捕获逻辑(既没加try/catch,也没在函数末尾加.catch()),这直接触发了未处理的Promise拒绝。
  • connection变量是在if (message.member.voice.channel)代码块里定义的,外面的const dispatcher = connection.playFile(...)根本拿不到这个变量,运行到这里肯定会抛出connection is not defined的错误,而这个错误在async函数里没被捕获,也会导致Unhandled Promise Rejection。
  • 你重复调用了两次client.login(),这完全是多余的,还可能引发登录冲突。
  • Discord.js v12及以后的版本里,playFile已经被弃用了,应该用play()方法来播放音频文件。

接下来是修复后的完整代码,我给你标注了每个修复点:

const Discord = require('discord.js');
const client = new Discord.Client();
const fs = require('fs');
const path = require('path'); // 引入path模块处理文件路径,避免系统路径问题

// 只保留一次登录调用
client.login('NzUzNzAwMzQ2MDI2Nzg2ODI2.X1qAJQ.K-2nBZOSxz8k0LAnGmNC_EGaKqQ');

// 移除多余的自执行async函数和无意义的throw()
client.on('message', async (message) => {
  if (!message.guild) return;

  if (message.content === '/join') {
    // 用try/catch包裹所有可能出错的异步操作,捕获错误避免未处理的Promise拒绝
    try {
      if (message.member.voice.channel) {
        // 把connection变量提升到try块作用域内,确保后续代码能访问到
        const connection = await message.member.voice.channel.join();
        // 用path.resolve生成跨系统兼容的文件路径,同时替换弃用的playFile为play()
        const audioPath = path.resolve(__dirname, './Audio/gab.mp3');
        const dispatcher = connection.play(audioPath);
        
        // 给播放器添加错误监听,方便排查播放时的问题
        dispatcher.on('error', (err) => {
          console.error('音频播放出错:', err);
          message.reply('播放音频时出现错误!');
        });
      } else {
        message.reply('You need to join a voice channel first!');
      }
    } catch (err) {
      // 统一捕获所有异步错误,输出日志并给用户反馈
      console.error('处理/join命令时出错:', err);
      message.reply('执行命令时出现错误,请稍后再试!');
    }
  }
});

再给你拆解下关键修复逻辑:

  • 移除了无意义的自执行async函数和throw()语句,避免主动抛出未处理的错误。
  • 用try/catch包裹所有异步操作,确保任何抛出的错误都会被捕获处理,不会触发Unhandled Promise Rejection。
  • 调整了connection变量的作用域,解决了“变量未定义”的问题。
  • 替换了弃用的音频播放方法,并用path.resolve()处理文件路径,适配不同操作系统。
  • 只保留一次client.login()调用,避免登录冲突。

另外,如果你想让Node.js在遇到未处理的Promise拒绝时直接终止进程(方便快速定位问题),可以启动项目时加上CLI参数:--unhandled-rejections=strict。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:17:33