Skip to content
This repository has been archived by the owner on Jan 8, 2022. It is now read-only.

async/await strange undefined behavior #96

Open
ryanpag3 opened this issue Dec 24, 2021 · 6 comments
Open

async/await strange undefined behavior #96

ryanpag3 opened this issue Dec 24, 2021 · 6 comments
Labels
bug Something isn't working rest

Comments

@ryanpag3
Copy link

ryanpag3 commented Dec 24, 2021

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

@ryanpag3 ryanpag3 added bug Something isn't working need repro labels Dec 24, 2021
@vladfrangu
Copy link
Member

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!

@Jiralite
Copy link
Member

Jiralite commented Dec 26, 2021

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.

@ryanpag3
Copy link
Author

ryanpag3 commented Dec 26, 2021

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.

@kyranet
Copy link
Member

kyranet commented Dec 26, 2021

This is because timers are unref'd:

delay = sleep(timeout, undefined, { ref: false });

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.

@KhafraDev
Copy link

It's also weird that using .then/.catch would solve the issue because await uses the Promise prototype methods under the hood.

@ryanpag3
Copy link
Author

ryanpag3 commented Jan 5, 2022

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working rest
Projects
None yet
Development

No branches or pull requests

5 participants