discord.js 中的 MySQL

Posted

技术标签:

【中文标题】discord.js 中的 MySQL【英文标题】:MySQL in discord.js 【发布时间】:2021-08-05 15:57:32 【问题描述】:

我正在设置一个机器人来处理 mysql 数据库。 它之前有效,现在在我添加 MySQL 代码后它不起作用:

(node:12312) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'query' of undefined
    at C:\Users\Admin\Desktop\MuffinMod Data\MuffinMod - Recode\Bot\events\ready.js:4:20
    at Map.forEach (<anonymous>)
    at module.exports (C:\Users\Admin\Desktop\MuffinMod Data\MuffinMod - Recode\Bot\events\ready.js:3:25)
    at Client.emit (events.js:315:20)
    at WebSocketManager.triggerClientReady (C:\Users\Admin\Desktop\MuffinMod Data\MuffinMod - Recode\node_modules\discord.js\src\client\websocket\WebSocketManager.js:431:17)
    at WebSocketManager.checkShardsReady (C:\Users\Admin\Desktop\MuffinMod Data\MuffinMod - Recode\node_modules\discord.js\src\client\websocket\WebSocketManager.js:415:10)
    at WebSocketShard.<anonymous> (C:\Users\Admin\Desktop\MuffinMod Data\MuffinMod - Recode\node_modules\discord.js\src\client\websocket\WebSocketManager.js:197:14)
    at WebSocketShard.emit (events.js:315:20)
    at WebSocketShard.checkReady (C:\Users\Admin\Desktop\MuffinMod Data\MuffinMod - Recode\node_modules\discord.js\src\client\websocket\WebSocketShard.js:475:12)
    at WebSocketShard.onPacket (C:\Users\Admin\Desktop\MuffinMod Data\MuffinMod - Recode\node_modules\discord.js\src\client\websocket\WebSocketShard.js:447:16)
(node:12312) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function 
without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)       
(node:12312) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

index.js:

require('dotenv').config();

//Database
let connection;
(async () => 
    connection = await require('./database/db.js');
)();
//Bot
const Discord = require("discord.js");
const client = new Discord.Client( partials: ['MESSAGE', 'CHANNEL', 'REACTION'], restRequestTimeout: 50000 );
const guildSettings = new Map();
client.commands = new Discord.Collection();
client.events = new Discord.Collection();
const DisTube = require('distube');
client.distube = new DisTube(client,  searchSongs: false, emitNewSongOnly: true );
['command', 'event'].forEach(handler =>
    require(`./Bot/handlers/$handler`)(client, Discord, connection);
);
await client.login(process.env.TOKEN);

ready.js:

module.exports = async(Discord, client, connection) => 
    console.log(`Bot online. ($client.user.tag)`);
    client.guilds.cache.forEach(guild => 
        connection.query(
            `SELECT * FROM GuildConfigurable WHERE guildID = $guild.id`
        ).then(result => 
            guildSettings.set(guild.id, result[0][0]);
        ).catch(err => console.log(err));
    );

db.js:

const sql = require('mysql2/promise');
module.exports = sql.createConnection(
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    user: process.env.DB_USERNAME,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
)
.then(()=>console.log(`Connected to MySQL Database.`))
.catch(err=>console.error(err));

我认为这是在 db.js 文件可以返回连接之前执行的 ready.js 文件的错误,但不知道如何修复它。 谢谢

【问题讨论】:

提示与您的问题无关,使用SELECT id FROM GuildConfigurable WHERE guildID = .. 这样 MySQL 服务器不会浪费带宽和精力返回不需要的数据。 错误来自你的ready.jsconnection返回未定义。 @Elitezen 是的,我认为机器人正在登录并且在 db.js 可以返回数据库连接之前执行 ready.js 【参考方案1】:

由于您的 async 方法只在 promise 解决后设置 connection 变量,所以在您使用它来设置事件处理程序时它仍然是未定义的。

您可以将connection 保留为每次需要时等待的承诺,或者将创建移动到与其消费者相同的异步函数中(如下所示)

require('dotenv').config();

//Bot
const Discord = require("discord.js");
const client = new Discord.Client( partials: ['MESSAGE', 'CHANNEL', 'REACTION'], restRequestTimeout: 50000 );
const guildSettings = new Map();
client.commands = new Discord.Collection();
client.events = new Discord.Collection();
const DisTube = require('distube');
client.distube = new DisTube(client,  searchSongs: false, emitNewSongOnly: true );

(async () => 
    const connection = await require('./database/db.js');

    ['command', 'event'].forEach(handler =>
      require(`./Bot/handlers/$handler`)(client, Discord, connection);
);

    await client.login(process.env.TOKEN);

)();

db.js 中,您还需要从Promise 链的最后一步返回connection

const sql = require('mysql2/promise');
module.exports = sql.createConnection(
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    user: process.env.DB_USERNAME,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
)
.then((connection) => 
    console.log(`Connected to MySQL Database.`);
    return connection;
)
.catch(err=>console.error(err));

【讨论】:

刚刚注意到connection 仍将是undefined,因为它不是从db.js 返回的 - 相应地更新了答案

以上是关于discord.js 中的 MySQL的主要内容,如果未能解决你的问题,请参考以下文章

Discord.py 中的 Discord.js 的 `user.tag` 和 `user.username`?

使用 Discord.js 使用 Discord Bot 将语音频道中的所有人静音

discord.js 中的停止循环

Discord.js 中的 MySQL 黑名单系统

discord.js - 一个命令中的愚蠢错误

替换 Discord.JS 中的某些字符