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

ChannelManager.add calling on a deleted channel creating error #5635

Closed Evercreeper closed 3 years ago

Evercreeper commented 3 years ago

Please describe the problem you are having in as much detail as possible: Hey. I host a bot with channel-creation capabilities for a discord server. It is hosted off of a Replit IDE

Recently, our bot has been getting Discord.js internal errors that we cannot catch regarding our channel creation system. (this specific error message from our test build)

/home/runner/RPM-TEST-BUILD/node_modules/discord.js/src/managers/ChannelManager.js:23
    const existing = this.cache.get(data.id);
                                         ^

TypeError: Cannot read property 'id' of undefined
    at ChannelManager.add (/home/runner/RPM-TEST-BUILD/node_modules/discord.js/src/managers/ChannelManager.js:23:42)
    at Invite._patch (/home/runner/RPM-TEST-BUILD/node_modules/discord.js/src/structures/Invite.js:95:41)
    at new Invite (/home/runner/RPM-TEST-BUILD/node_modules/discord.js/src/structures/Invite.js:15:10)
    at InviteCreateAction.handle (/home/runner/RPM-TEST-BUILD/node_modules/discord.js/src/client/actions/InviteCreate.js:15:20)
    at Object.module.exports [as INVITE_CREATE] (/home/runner/RPM-TEST-BUILD/node_modules/discord.js/src/client/websocket/handlers/INVITE_CREATE.js:4:31)
    at WebSocketManager.handlePacket (/home/runner/RPM-TEST-BUILD/node_modules/discord.js/src/client/websocket/WebSocketManager.js:386:31)

Now at first, I thought it could be OUR code. The latest error happened when someone did our creation command with a bunch of emojis "-uca text 60 πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€". I figured there was a problem with channel creation. Then after figuring out it was not on my end, I actually looked at the error better.

My UCA content is a category which is at the TOP of our channel list. This means any defaulted invites that go above "uca-info" may be sent to a deleted channel!

Image: https://prnt.sc/12y6tie

Now lets go look at the code featured in the ChannelManager:

add(data, guild, cache = true) {
    const existing = this.cache.get(data.id); // As you can see, a channel should always exist when this is called. However, when Discord defaulting picks the invite, it can be to a channel that no longer exists, therefore no .id
    if (existing) {
      if (existing._patch && cache) existing._patch(data);
      if (guild) guild.channels.add(existing);
      return existing;
    }

    const channel = Channel.create(this.client, data, guild);

    if (!channel) {
      this.client.emit(Events.DEBUG, `Failed to find guild, or unknown type for channel ${data.id} ${data.type}`);
      return null;
    }

    if (cache) this.cache.set(channel.id, channel);

    return channel;
  }

Now I am no expert, this being my first ever github issue I have created, how ever I do not know if this is a Discord API issue or a Discord.js code issue. As I put in the comment, it seems that this is being called with no data and therefore the id property is absent.

I do not really know anything past what I speculate here. It seems to be an invite issue, but how could a default invite be invoked when I don't call on Discord.js to handle an invite? Does discord.js handle invites?

Anyhow I appreciate you taking your time to deal with this issue. Again, I am sorry for not being super pro who can automatically find what part is wrong, but hopefully the information I provided is beneficial.

Further details:

Evercreeper commented 3 years ago

Sorry if I broke any formats. Currently 1:00 AM for me and I am just trying to report this issue as best as I can. If you do want my specific code to verify it is not on my end, please tell me and I will provide right away.

Evercreeper commented 3 years ago

After further investigation, I am 99% sure this is an internal discord.js error and should have a higher priority.

I am currently running uptime tests and I am going back checking the last bot activity when it crashes from this error. This is the only error currently crashing my bot. After some tests, I found out that my channel creator WAS NOT at fault here.

My bot would crash to this error after a few things such as:

Now that we know it is not on my end, what could be causing this issue? As I stated in my original issue, I haven't done my fair share of investigating internally and I don't know what each part of the error is.

monbrey commented 3 years ago

As far as I can tell looking at this

This should be impossible according to the API docs for an Invite - channel is not optional https://discord.com/developers/docs/resources/invite#invite-object-invite-structure

Evercreeper commented 3 years ago

Yeah, this seems to be really strange. Thank you for the info. Is there a way I can catch the discord.js error to at least maintain the uptime of the bot while I figure out the root cause?

I looked at the errors guide and the closest thing I set up was a shardError and it does not catch this, although the error is really in the module and not in the websocket itself so that is expected.

Sorry again if I am missing any formatting or I am just being generally unhelpful here, first time making an issue and first time dealing with an impossible bug that I can't find out what is wrong.

TranquillyUnpleasant commented 3 years ago

Ive had the same error happening. Since the bot doesn't do anything with invites im fairly certain the error is within the library itself. The stack trace also points to such. Here is the trace:

/home/io/discordbot/ModBotv2/node_modules/discord.js/src/managers/ChannelManager.js:23
    const existing = this.cache.get(data.id);
                                         ^

TypeError: Cannot read property 'id' of undefined
    at ChannelManager.add (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/managers/ChannelManager.js:23:42)
    at Invite._patch (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/structures/Invite.js:95:41)
    at new Invite (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/structures/Invite.js:15:10)
    at InviteDeleteAction.handle (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/client/actions/InviteDelete.js:15:20)
    at Object.module.exports [as INVITE_DELETE] (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/client/websocket/handlers/INVITE_DELETE.js:4
:31)
    at WebSocketManager.handlePacket (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/client/websocket/WebSocketManager.js:384:31)
    at WebSocketShard.onPacket (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/client/websocket/WebSocketShard.js:444:22)
    at WebSocketShard.onMessage (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/client/websocket/WebSocketShard.js:301:10)
    at WebSocket.onMessage (/home/io/discordbot/ModBotv2/node_modules/ws/lib/event-target.js:132:16)
    at WebSocket.emit (events.js:314:20)
Thrown at:
    at add (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/managers/ChannelManager.js:23:42)
    at _patch (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/structures/Invite.js:95:41)
    at Invite (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/structures/Invite.js:15:10)
    at handle (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/client/actions/InviteDelete.js:15:20)
    at module.exports (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/client/websocket/handlers/INVITE_DELETE.js:4:31)
    at handlePacket (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/client/websocket/WebSocketManager.js:384:31)
    at onPacket (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/client/websocket/WebSocketShard.js:444:22)
    at onMessage (/home/io/discordbot/ModBotv2/node_modules/discord.js/src/client/websocket/WebSocketShard.js:301:10)
    at onMessage (/home/io/discordbot/ModBotv2/node_modules/ws/lib/event-target.js:132:16)
    at emit (events.js:314:20)

Notably, its on the invite delete event in this case, which only happened within this guild due to a timeout, no invites have been manually deleted, and the bot is only in one guild.

charlieTheBotDev commented 3 years ago

Also seeing this issue today repeatedly and it's crashing my bot with seemingly no way to handle it.

The crash seems to be more like an infinite loop / unresponsive error rather than a standard process crash (which I handle and auto-restart) so the bot just hangs indefinitely.

[RGB] (2021-05-26T09:12:57.968Z) Process: Uncaught Exception TypeError: Cannot read property 'id' of undefined
    at ChannelManager.add (/root/git/rgb/bot/node_modules/discord.js/src/managers/ChannelManager.js:23:42)
    at Invite._patch (/root/git/rgb/bot/node_modules/discord.js/src/structures/Invite.js:95:41)
    at new Invite (/root/git/rgb/bot/node_modules/discord.js/src/structures/Invite.js:15:10)
    at InviteDeleteAction.handle (/root/git/rgb/bot/node_modules/discord.js/src/client/actions/InviteDelete.js:15:20)
    at Object.module.exports [as INVITE_DELETE] (/root/git/rgb/bot/node_modules/discord.js/src/client/websocket/handlers/INVITE_DELETE.js:4:31)
    at WebSocketManager.handlePacket (/root/git/rgb/bot/node_modules/discord.js/src/client/websocket/WebSocketManager.js:384:31)
    at WebSocketShard.onPacket (/root/git/rgb/bot/node_modules/discord.js/src/client/websocket/WebSocketShard.js:444:22)
    at WebSocketShard.onMessage (/root/git/rgb/bot/node_modules/discord.js/src/client/websocket/WebSocketShard.js:301:10)
    at WebSocket.onMessage (/root/git/rgb/bot/node_modules/ws/lib/event-target.js:132:16)
    at WebSocket.emit (events.js:315:20)

I'm getting this from process.on('uncaughtException', (error) => console.log(...)

I'm listening to the following events from client:

guildDelete
guildCreate
warn
error
rateLimit
error
shardError
message

None of which seem to be triggering the issue.

I was on 12.5.1 but have updated to 12.5.3 to see if the issue goes away (although as the OP was using 12.5.3 I doubt it)

I suspect it's to do with inviting a bot to a stage channel but I can't seem to do that on my server so 🀷

Edit: I've tried to catch it with every event handler to no avail. Seems that the issue may be related to a change in the Discord API which as they have been touching Stage channels recently would make sense

I've manually patched my node_modules with a small if statement inside the top of add for node_modules/discord.js/src/managers/ChannelManager.js

  add(data, guild, cache = true) {
    if (!data) {
      this.client.emit(Events.DEBUG, `No data provided`);
      return null;
    }

(Basically a copy of the !channel block so hopefully won't cause any problems)

For reference, the reason it makes your bot 'hang' is because the webhook handler never completes (i.e. it doesn't return anything) so simply adding the return null; is sufficient, I added the debug log so I know when it happens :)

Evercreeper commented 3 years ago

As you say @c-frater, it really is an easy fix like that. However, this still doesn't stop this rogue invite-create call and I fear until someone finds out what is exactly going wrong, this wont be publicly patched.

I think for now I will have to do the same as you and change our node_modules. Thanks for the fix πŸ‘

charlieTheBotDev commented 3 years ago

Yeah, just for complete explicitness this fixes the symptom of whatever is calling that rouge invite-create and most definitely needs to be fixed at the source in D.js rather than applying my change blindly and hiding the real issue away.

Shared purely as a workaround until they work out the root cause πŸ‘

ExpErgio commented 3 years ago

I need help. I did all @c-frater said in _nodemodules/discord.js/src/managers/ChannelManager.js

'use strict';

const BaseManager = require('./BaseManager');
const Channel = require('../structures/Channel');
const { Events } = require('../util/Constants');

/**
 * A manager of channels belonging to a client
 * @extends {BaseManager}
 */
class ChannelManager extends BaseManager {
  constructor(client, iterable) {
    super(client, iterable, Channel);
  }

  /**
   * The cache of Channels
   * @type {Collection<Snowflake, Channel>}
   * @name ChannelManager#cache
   */

  add(data, guild, cache = true) {
    if(!data) { // ---------------------------------------------   HERE
      this.client.emit(Events.DEBUG, `No data provided`);
      return null;
    } // --------------------------------------------------------  HERE
    const existing = this.cache.get(data.id);
    if (existing) {
      if (existing._patch && cache) existing._patch(data);
      if (guild) guild.channels.add(existing);
      return existing;
    }

but it doesnt work. When I place my bot in a Stage Channel, it crash. In my console, I have this error:

C:\Users\Usuario\Desktop\BOT_Alejandreta 2.0\node_modules\discord.js\src\client\voice\networking\VoiceWebSocket.js:123
        server_id: this.connection.channel.guild.id,
                                           ^

TypeError: Cannot read property 'guild' of undefined
    at VoiceWebSocket.onOpen (C:\Users\Usuario\Desktop\BOT_Alejandreta 2.0\node_modules\discord.js\src\client\voice\networking\VoiceWebSocket.js:123:44)
    at WebSocket.onOpen (C:\Users\Usuario\Desktop\BOT_Alejandreta 2.0\node_modules\ws\lib\event-target.js:144:16)
    at WebSocket.emit (events.js:315:20)
    at WebSocket.setSocket (C:\Users\Usuario\Desktop\BOT_Alejandreta 2.0\node_modules\ws\lib\websocket.js:177:10)
    at ClientRequest.<anonymous> (C:\Users\Usuario\Desktop\BOT_Alejandreta 2.0\node_modules\ws\lib\websocket.js:671:15)
    at ClientRequest.emit (events.js:315:20)
    at TLSSocket.socketOnData (_http_client.js:547:11)
    at TLSSocket.emit (events.js:315:20)
    at addChunk (internal/streams/readable.js:309:12)
    at readableAddChunk (internal/streams/readable.js:284:9)
    at TLSSocket.Readable.push (internal/streams/readable.js:223:10)
    at TLSWrap.onStreamRead (internal/stream_base_commons.js:188:23)
SpaceEEC commented 3 years ago

This should have been fixed by #4882, can somebody provide some steps to reproduce this error?

charlieTheBotDev commented 3 years ago

@ExpErgio the issue you're having is unrelated to ChannelManager.add - It may be a new/already reported issue elsewhere

Evercreeper commented 3 years ago

This should have been fixed by #4882, can somebody provide some steps to reproduce this error?

This is exactly my problem. There IS no way to reproduce this error and seems to happen at random. I can provide some more information about the server itself, but other than every since I forked and did c-frater's solution I have completed stopped the error.

I wish there were more to say but unfortunately I do not have a definite answer. I must say however, this error did not start occurring until about April.

SpaceEEC commented 3 years ago

I'm really puzzled about how that could be happening, since we explicitly check for the channel's truthiness in both of the action handlers. πŸ˜…

Can you log the data along it's way to the error? Maybe that could give us any clues about why this is happening.

Relevant places (although those are already visible in the stacktrace):

https://github.com/discordjs/discord.js/blob/51551f544b80d7d27ab0b315da01dfc560b2c115/src/client/actions/InviteCreate.js#L15 https://github.com/discordjs/discord.js/blob/51551f544b80d7d27ab0b315da01dfc560b2c115/src/client/actions/InviteDelete.js#L15 https://github.com/discordjs/discord.js/blob/51551f544b80d7d27ab0b315da01dfc560b2c115/src/structures/Invite.js#L15 https://github.com/discordjs/discord.js/blob/51551f544b80d7d27ab0b315da01dfc560b2c115/src/structures/Invite.js#L95 https://github.com/discordjs/discord.js/blob/51551f544b80d7d27ab0b315da01dfc560b2c115/src/managers/ChannelManager.js#L23

iCrawl commented 3 years ago

Closing because stale, open a new issue if this is still a problem.