discord.js-modules
discord.js-modules copied to clipboard
async/await strange undefined behavior
Issue description
When I deploy the following code using async/await my application exits immediately with no error code intermittently (usually 1 of every 4 or 5 tries).
Code sample
export async function deploy() {
logger.debug(`deploying slash commands`);
try {
if (process.env.NODE_ENV !== 'production') {
// register with test server
await rest.put(
Routes.applicationGuildCommands(process.env.DISCORD_APPLICATION_ID as string, process.env.TEST_GUILD_ID as string),
{
body: mappedCommands
}
)
} else {
// register globally in production
await rest.put(
Routes.applicationCommands(process.env.DISCORD_APPLICATION_ID as string),
{
body: mappedCommands
}
);
}
logger.debug(`slash commands registered`);
} catch (e) {
logger.error(`Failed to deploy slash commands.`, e);
throw e;
}
}
discord.js version
13.13.1
Node.js version
v16.13.0
Operating system
MacOS
Priority this issue should have
Medium (should be fixed soon)
Which partials do you have configured?
No Partials
Which gateway intents are you subscribing to?
GUILDS
I don't see how this is an issue with the rest module, but it might be with your code. Please make a minimum reproduction sample, and report back if the issue persists!
Hiya @vladfrangu, I think this may be a minimum reproduction sample:
import { setTimeout } from "node:timers/promises";
import { Routes } from "discord-api-types/v9";
import { REST } from "@discordjs/rest";
class test {
REST = new REST().setToken(process.env.DISCORD_TOKEN ?? "");
async deleteMessages(channelId, messageIds) {
for (const messageId of messageIds) {
await this.REST.delete(Routes.channelMessage(channelId, messageId)).catch(() => null); // Ignore errors
// await setTimeout(1000);
}
}
};
const testing = new test();
const messageIds = []; // Put message ids here
const output = await testing.deleteMessages("channel_id", messageIds);
console.log(output);
Populate the messageIds
array with message ids to be deleted (put at least 5 in). After running this script, you'll find that the script terminates after about a second with having only deleted about 2-3 messages. Put 50 message ids in, and the result will be the same.
If the process is kept alive, all message ids will be deleted. Additionally, uncommenting the await setTimeout(1000)
will allow for all messages to be deleted. It seems for some reason the requests just drop and the process finishes despite the messages not having been deleted yet.
Also, console.log(output)
never outputs anything unless the process is kept alive enough for all messages to be deleted.
Thanks for that code sample @Jiralite that is basically the behavior I’m seeing as well with command deployment. async/await doesn’t seem to work right with this module.
This is because timers are unref'd:
https://github.com/discordjs/discord.js-modules/blob/90704400d2ff8043993d59fcb02e9c50eb5a8227/packages/rest/src/lib/handlers/SequentialHandler.ts#L255
Since the sleep is done with ref: false
, the event loop does not wait for the timeout to finish, albeit it's an interesting issue here, since it should at least wait because await
can keep a process up as long as it's running in the main loop.
It's also weird that using .then/.catch would solve the issue because await uses the Promise prototype methods under the hood.
It's also weird that using .then/.catch would solve the issue because await uses the Promise prototype methods under the hood.
I did some more testing on this and I don't think I was accurate about that. They had similar issues.