discordjs / discord.js

A powerful JavaScript library for interacting with the Discord API
https://discord.js.org
Apache License 2.0
25.22k stars 3.96k forks source link

Unknown Message randomly on Message.react calls #4656

Closed Stantz closed 4 years ago

Stantz commented 4 years ago

Please describe the problem you are having in as much detail as possible: Bot message reactions are failing with error code: 10008 Unknown Message. Code has not changed, code has been very consistently working for a couple months. The last couple days has been failing to add message reactions (or reactions show up much later after other bot actions are triggered)

Include a reproducible code sample here, if possible:

    function sendMesssage(channel: TextChannel) {
        const message = new MessageEmbed().setTitle("Test");
        channel.send(message).then((msg) => setupEmojiReactions(msg)).catch(console.log);       
    }

    function setupEmojiReactions(message: Message): void {
        UnicodeEmojiRsvpOptions.Raid.map((x) => message.react(x).catch(console.log));
    }

Further details:

Relevant client options:

almostSouji commented 4 years ago

This is not a reproducible code sample. The idea behind that section is to provide a complete and minimal sample on an isolated environment so other people can reproduce your issue without needing to guess your surrounding infrastructure additionally to making sure that the part of code you suspect to be the culprit actually is the part causing the issue.

Since you seem to catch the rejection please compare the logged message ID (part of the API path the request fails on, which is provided by our custom error structure) to the id of the message you pass in there.

I can not see how that error could be thrown by that piece of code (hence the aforementioned "isolation" aspect of minimal reproducible code samples) unless it posts it in a channel where its own answer gets deleted by the bot itself/another bot/staff before the reaction call can resolve.

If reactions "show up much later" that is at least an indicator that you are probably trying to add a lot of reactions, being limited in the process of doing so (can't be too sure on that one without further debugging attempts from your side, for example logging the "rateLimit" event )


Please try to reproduce the issue yourself on a fresh bot. If you can't reproduce it, it's very likely that we can't either and the code sample in question is not enough.

Boilerplate: https://discord.js.org/#/docs/main/stable/examples/ping Minimal Reproducible sample: https://stackoverflow.com/help/minimal-reproducible-example

Stantz commented 4 years ago

@almostSouji thank you for the feedback. The problem with a reproducible example is that its not consistent. I will work on a smaller isolated example to share, but there is no guarantee (based on what I'm seeing) that you will be able to reproduce it unless you run that bot and made requests against it over a wide enough time frame. Since I see most of the issues in heroku, it would require you to deploy this to heroku with the same stack to ensure a proper test case for reproducing.

I did check the message ID from the error output and I found nothing to indicate the message does not exist.

As to your point about the number of reactions and the rate limit. This bot is only running in a single test server and at the time of failure and is attempting to post three messages with 4 reactions each. Or its happening when the bot posts a single message with 4 reactions. I will take your recommendation about logging from the rateLimit event to see if I am running against that. Thank you.

My primary goal was to get this logged and on record in the event that other start experiencing something similar. I will close this ticket with this comment and work on a smaller reproducible example and re-submit it if I am able to create an example that consistently fails.

Sorry for wasting your time, but I appreciate the response.

Stantz commented 4 years ago

After taking your advice @almostSouji to track the rateLimit event I found that I was hitting that when attempting to add two reactions right after each other. I can't prove that this was causing the reactions to not show up in the channel, but I am curious as to why posting two in a row triggers the rateLimit event?

here is a complete coding sample:

require('dotenv').config();
import Discord, { RateLimitData, TextChannel } from 'discord.js';

process.on('unhandledRejection', (error: any) => {
    if (error) {
        console.error(`unhandledRejection: ${error.message}`);
    }
});

// Initialize Discord Bot
const bot = new Discord.Client();

bot.on('ready', () => {
    const channel = bot.channels.cache.get("{channel_id}") as TextChannel;

    channel.send("Test").then((msg) => {
        msg.react("1️⃣").then(() => {
            msg.react("2️⃣");
        });
    });
});

bot.on('rateLimit', (rateLimitInfo: RateLimitData) => {
    console.log(`**RATE LIMIT** Timeout (ms): ${rateLimitInfo.timeout} - Max Requests: ${rateLimitInfo.limit} - Path: ${rateLimitInfo.path}`);
});

bot.login(process.env.BOT_TOKEN);

Any insight would be greatly appreciated. Thank you.

almostSouji commented 4 years ago

Reactions not showing up at all but the react call resolving is not really possible unless the API is having a bad day.

The rate limit being hit is expected, discord.js delays the API call according to the rate limit headers we get from the API. This can appear "slower" than with other libraries if you use the default restTimeOffset option of 500 (ms), which we added as a safety feature for bots running on bad connections.

The "unknown message" error does definitely not come from that. That means you are trying to react to a message that does not exist (anymore).

Stantz commented 4 years ago

Thank you again for your help/insight. I had another question, is there anything that would cause a message to "not exist" right after you've created it (other than not awaiting the operation)? If I am attempting to react to that message after calling:

const message = await channel.send("some message");
message.react(emoji);

Does awaiting the resolved promise ensure the message exists? or can that assumption not be made?

almostSouji commented 4 years ago

The promise returned by TextBasedChannel#send resolves with the message it just created (or an array of Message objects, if the split option is used). If anything goes wrong during this call the promise will reject instead as per Promise specification.

bakemono-dev commented 2 years ago

For anyone else that encounters this issue, make sure you're not using ephemeral replies. Neither the bot nor the receiving user can react to the ephemeral message because ephemerals don't support reactions.