discordjs / discord.js

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

[Uncaught Rejection]: Error: Authentication failed #9725

Closed AleeQuintino closed 1 year ago

AleeQuintino commented 1 year ago

Which package is this bug report for?

discord.js

Issue description

I have an application that runs multiple clients.

For some reason, some are returning Authentication Failed, and even if I destroy the section and start it again, it keeps giving this error. The token is correct because when I destroy it with .destroy() and rebuild the client with .login(token) it logs correctly.

Another point that I noticed is that this error only happens in the client that is at the top, if I destroy it and don't start again, the next one that is at the top starts to give the error.

I build the clients like this:

db: {CLIENTID, TOKEN}

then I do a for on all DB records, and execute:

const { Partials, Client } = require("discord.js")

const clients = {}

clients[db.CLIENTID] = new Client({ intents, partials: [Partials.Channel] })

//my handlers with all listeners: ready, interactionCreate and etc

await clients[db.CLIENTID].login(db.TOKEN)

So I have a process.on to collect general errors that stop the process, generating a log for me. built like this:

process.on("uncaughtException", async (exception) => {

})

then inside process.on I check which client generated the error by looking for the ws status like this:

clients[for.CLIENTID].ws.status === 0 && exception.message == 'Authentication failed'

then it gives this error here:

[9:57 AM] error: unexpected error occurred that would stop the code

{
  "clientId": "1066125729001132052",
  "error": {
    "message": "Authentication failed",
    "stack": "Error: Authentication failed\n    at WebSocketShard.onClose (/application/node_modules/@discordjs/ws/dist/index.js:1035:15)\n    at WebSocket.emit (node:events:513:28)\n    at WebSocket.emitClose (/application/node_modules/ws/lib/websocket.js:258:10)\n    at TLSSocket.socketOnClose (/application/node_modules/ws/lib/websocket.js:1264:15)\n    at TLSSocket.emit (node:events:525:35)\n    at node:net:322:12\n    at TCP.done (node:_tls_wrap:588:7)"
  }
}

Code sample

(async () => {

    const { Partials, Client } = require('discord.js')

    const db = [
        { CLIENTID: 'clientid1', TOKEN: 'token1' },
        { CLIENTID: 'clientid2', TOKEN: 'token2' },
        { CLIENTID: 'clientid3', TOKEN: 'token3' },
        { CLIENTID: 'clientid4', TOKEN: 'token4' }
    ]

    const clients = {}

    // Caso de algum erro que vai quebrar o código, ele loga e destrói o client
    process.on("uncaughtException", async (exception) => {

        // Verifica qual client causou a exceção
        for (const clientId in clients) {

            // Verifica as propriedades do client
            if (clients.hasOwnProperty(clientId)) {

                let statusShards
                try {
                    statusShards = await clients[clientId].ws.shards.get(0).status
                } catch (error) {
                    statusShards = 0
                }

                // Verifica se existe o client, se ele possui a propriedade ws e se o Status dele é 0
                if (clients[clientId] && clients[clientId].ws && clients[clientId].ws.status === 0 && exception.message == 'Authentication failed') {

                    console.log(`Authentication failed`, { clientId, createInstance, error: { message: exception.message, stack: exception.stack } })

                    clients[clientId].destroy()
                    clients[clientId] = null

                    return

                } else if (clients[clientId] && clients[clientId].ws && statusShards === 1) {

                    console.log(`client message intent are not enabled`, { clientId: clientId, error: { message: exception.message, stack: exception.stack } })

                    clients[clientId].destroy()
                    clients[clientId] = null

                    return

                }

            }
        }

        console.log(`unexpected error occurred that would break the code`, { error: { message: exception.message, stack: exception.stack } })

    })

    for (const key of db) {

        clients[key.CLIENTID] = new Client({ intents: 130809, partials: [Partials.Channel] })

        clients[key.CLIENTID].on('ready', () => {
            console.log(`O bot está online com o nome: ${clients[key.CLIENTID].user.tag}`);
        });

        await clients[key.CLIENTID].login(key.TOKEN).then(r => { console.log(r) }).catch(e => { console.log(e) })

    }

})();

Versions

discord.js v14.11.0 nodejs v18.16.0

Issue priority

High (immediate attention needed)

Which partials do you have configured?

Channel

Which gateway intents are you subscribing to?

Guilds, GuildEmojisAndStickers, GuildIntegrations, GuildWebhooks, GuildInvites, GuildVoiceStates, GuildMessages, GuildMessageReactions, GuildMessageTyping, DirectMessages, DirectMessageReactions, DirectMessageTyping, MessageContent, GuildScheduledEvents

I have tested this issue on a development release

No response

Qjuh commented 1 year ago

Is there a reason you pass TOKEN and not db.TOKEN to the login call? Because the latter would match the data structure you mentioned, while the former would make each client try to login with the same token.

AleeQuintino commented 1 year ago

orque o último corresponderia à estrutura de dados que você mencionou, enquanto o primeiro faria com que cada cliente tentasse fazer login com o mesmo token.

sorry, I think I expressed myself badly. I updated the issue

I have the Token and the Client stored in the DB, a token for each client.

I run the .login with the specific client token

Qjuh commented 1 year ago

Your code sample isn’t really reproducible though without you showing the actual loop you use. So if you really think this to be a bug provide a reproducible sample.

AleeQuintino commented 1 year ago

Your code sample isn’t really reproducible though without you showing the actual loop you use. So if you really think this to be a bug provide a reproducible sample.

Sorry, I edited the issue and added the code sample. This is a simplified working sample of my code

Qjuh commented 1 year ago

Your code checking which one of your clients caused the error is flawed. You find the first client in your clients array with status Status.Ready = 0 so you look for the first that did succeed logging in. Not one that didn’t… so you‘re probably looking at the wrong place for a wrong token. And it is a wrong token for sure.

AleeQuintino commented 1 year ago

Your code checking which one of your clients caused the error is flawed. You find the first client in your clients array with status Status.Ready = 0 so you look for the first that did succeed logging in. Not one that didn’t… so you‘re probably looking at the wrong place for a wrong token. And it is a wrong token for sure.

How could I collect the client that has an authentication error efficiently, could you help me?

process.on("uncaughtException", async (exception) => {
  for (const clientId in clients) {
    if (clients.hasOwnProperty(clientId)) {
      try {
        await clients[clientId].ws.shards.get(0).status;
        continue;
      } catch (error) {
        console.log(`Erro no cliente ${clientId}:`, error);
        clients[clientId].destroy();
        clients[clientId] = null;
        // Se ocorreu um erro, retorna
        return;
      }
    }
  }
  console.log(`Ocorreu um erro inesperado que quebraria o código:`, exception);
});

Would that fix my problem? I want to implement and analyze my logs to check if it really is just an invalid token

Qjuh commented 1 year ago

If you need help fixing your problems please join the support discord server. Unless you can provide an actual reproducible code that shows this is a bug in discord.js and not an invalid token this issue can be closed.