'Async/Await function executing twice in Discord.js bot
I've been experimenting with a Discord bot in Node.js. I came across the problem of all functions not executing linearly, but asynchronously. I managed to introduce async/await to solve this issue, but now one of my function calls executes twice and I don't know why (The command !ec2-status prints twice on a given chat even though I only call it once). The routine that reacts to a message sent is as follows:
// Event: Message
client.on("messageCreate", msg => {
// Extract metadata from message
let msgServerID = msg.guildId;
let msgChannelID = msg.channelId;
let msgUserID = msg.author.id;
let msgUsername = msg.author.username;
// Select server and channel of current message
let msgServer = client.guilds.cache.get(msgServerID);
let msgChannel = msgServer.channels.cache.get(msgChannelID);
// Command (!status):
// Check AWS instance status if server is "Dev Server"
if (msg.content === "!ec2-status") {
const thingy = async () => {
let instanceStatuses = await getEC2Status();
let statusText = "Instance Info: \n";
for (const instanceID in instanceStatuses) {
statusText += `${instanceID}: ${instanceStatuses[instanceID]}\n`;
}
msg.reply(statusText);
}
thingy();
}
});
The function that gets triggered in order to get the status of my EC2 instances (the objective of the command) is the following:
// Function: Get the status of all EC2 instances
const getEC2Status = async () => {
// Variable to store the status of all instances
let instanceStatuses = {};
// Retrieve instance information without previous permission check (DryRun = False)
const results = await ec2.describeInstances({ DryRun: false }, (err, data) => {
// Return an error if an error ocurrs
if (err) {
console.log("Retrieve Instance Info: Error\n", err.stack);
}
else {
// Adds the info of each instance
data.Reservations.forEach(reservation => {
let instanceID = reservation.Instances[0].InstanceId;
let status = reservation.Instances[0].State.Name;
instanceStatuses[instanceID] = status;
});
console.log("Retrieve Instance Info: Success\n", instanceStatuses);
}
}).promise();
return instanceStatuses
}
I'm having a hard time wrapping my head around async/await, so that may be the problem. But I need someone to nudge me in the right direction. Right now, I'm a bit stuck.
Solution 1:[1]
Perhaps the following changes help:
- Make the entire
client.onfunction async, instead of only the singlethingy()function you define in there. - I'm not sure what the
.promise()is doing, but I don't think it makes sense to await something after which you call.promise(). Remove the.promise().
All in all, thus:
// Event: Message
client.on("messageCreate", async (msg) => {
// Extract metadata from message
let msgServerID = msg.guildId;
let msgChannelID = msg.channelId;
let msgUserID = msg.author.id;
let msgUsername = msg.author.username;
// Select server and channel of current message
let msgServer = client.guilds.cache.get(msgServerID);
let msgChannel = msgServer.channels.cache.get(msgChannelID);
// Command (!status):
// Check AWS instance status if server is "Dev Server"
if (msg.content === "!ec2-status") {
let instanceStatuses = await getEC2Status();
let statusText = "Instance Info: \n";
for (const instanceID in instanceStatuses) {
statusText += `${instanceID}: ${instanceStatuses[instanceID]}\n`;
}
msg.reply(statusText);
}
});
// Function: Get the status of all EC2 instances
const getEC2Status = async () => {
// Variable to store the status of all instances
let instanceStatuses = {};
// Retrieve instance information without previous permission check (DryRun = False)
const results = await ec2.describeInstances({ DryRun: false }, (err, data) => {
// Return an error if an error ocurrs
if (err) {
console.log("Retrieve Instance Info: Error\n", err.stack);
}
else {
// Adds the info of each instance
data.Reservations.forEach(reservation => {
let instanceID = reservation.Instances[0].InstanceId;
let status = reservation.Instances[0].State.Name;
instanceStatuses[instanceID] = status;
});
console.log("Retrieve Instance Info: Success\n", instanceStatuses);
}
});
return instanceStatuses
}
Without more information, I think these are the best first steps.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Dharman |
