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

Bot crash when initiating DM with a user #9007

Closed ghost closed 1 year ago

ghost commented 1 year ago

Which package is this bug report for?

discord.js

Issue description

  1. Install latest version of discord.js
  2. Enable Channel partial
  3. Run the bot and wait for DM
ERROR Uncaught Exception: TypeError: Cannot read properties of undefined (reading 'id')
    at DMChannel._patch (./node_modules/discord.js/src/structures/DMChannel.js:39:36)
    at new BaseChannel (./node_modules/discord.js/src/structures/BaseChannel.js:25:38)
    at new DMChannel (./node_modules/discord.js/src/structures/DMChannel.js:17:5)
    at createChannel (./node_modules/discord.js/src/util/Channels.js:30:17)
    at ChannelManager._add (./node_modules/discord.js/src/managers/ChannelManager.js:50:21)
    at MessageCreateAction.getPayload (./node_modules/discord.js/src/client/actions/Action.js:29:22)
    at MessageCreateAction.getChannel (./node_modules/discord.js/src/client/actions/Action.js:38:12)
    at MessageCreateAction.handle (./node_modules/discord.js/src/client/actions/MessageCreate.js:9:26)
    at module.exports [as MESSAGE_CREATE] (./node_modules/discord.js/src/client/websocket/handlers/MESSAGE_CREATE.js:4:32)
    at WebSocketManager.handlePacket (./node_modules/discord.js/src/client/websocket/WebSocketManager.js:352:31)

Code sample

No response

Package version

14.7.2-dev.1672747445-7dec892.0

Node.js version

18.12.1

Operating system

No response

Priority this issue should have

Medium (should be fixed soon)

Which partials do you have configured?

Channel

Which gateway intents are you subscribing to?

Guilds, GuildMembers, GuildPresences, GuildMessages, DirectMessages, MessageContent

I have tested this issue on a development release

7dec892

jaw0r3k commented 1 year ago

so its related to https://github.com/discordjs/discord.js/blob/7dec892218f7b470a5f8e78732a524a53da24d26/packages/discord.js/src/structures/DMChannel.js#L33 which is undefined

Jiralite commented 1 year ago

We are unable to reproduce this issue.

If you can still reproduce this, it would be interesting if you could add console.log(data); on line 31 here and report back your payload:

https://github.com/discordjs/discord.js/blob/7dec892218f7b470a5f8e78732a524a53da24d26/packages/discord.js/src/structures/DMChannel.js#L30-L32

Also, are you using a modified version of discord.js? Can you provide a code sample you are using to reproduce this (to ensure no mutations are happening)?

ghost commented 1 year ago

Will do. and I didn't modify any part of DJS.

ghost commented 1 year ago

We are unable to reproduce this issue.

If you can still reproduce this, it would be interesting if you could add console.log(data); on line 31 here and report back your payload:

https://github.com/discordjs/discord.js/blob/7dec892218f7b470a5f8e78732a524a53da24d26/packages/discord.js/src/structures/DMChannel.js#L30-L32

Also, are you using a modified version of discord.js? Can you provide a code sample you are using to reproduce this (to ensure no mutations are happening)?

{
  id: 'redacted',
  guild_id: undefined,
  recipients: [
    {
      avatar: 'redacted',
      avatar_decoration: null,
      bot: true,
      discriminator: '6738',
      id: 'redacted',
      public_flags: 65536,
      username: 'redacted'
    }
  ]
}

And I think I figured out the reason. This issue only happens when the sender is bot itself. (Bot to User)

So reproducible code would be a code that send DM to a user.

Jiralite commented 1 year ago

Just a question, how consistently can you reproduce this? I cannot seem to reproduce this when a bot initiates a direct message or when it receives a direct message, both in the scenario of initiating a direct message for the first time and using an existing direct message channel.

ghost commented 1 year ago

Just a question, how consistently can you reproduce this? I cannot seem to reproduce this when a bot initiates a DM or when it receives a DM, both in the scenario of initiating a DM for the first time and using an existing DM.

I'm afraid that I can't give exact answer, but my bot sends DM to the server owner when they add it. So I think it's 'whenever a user adds the bot to their server'

Jiralite commented 1 year ago

Can you not provide a code sample? It should be easy if you're able to reproduce that frequently?

ghost commented 1 year ago

Can you not provide a code sample? It should be easy if you're able to reproduce that frequently?

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

const client = new Client({
  partials: [Partials.Channel],
  intents: [GatewayIntentBits.Guild],
});

client.on('guildCreate', async (guild) => {
  const owner = await guild.fetchOwner();
  await owner.send('thx for adding my bot').catch(() => null);
});

client.login('token');
Jiralite commented 1 year ago

Do you use sharding?

ghost commented 1 year ago

Do you use sharding?

Yes, I'm using it.

Jiralite commented 1 year ago

We managed to get a reproduction.

Turns out this is a minimal reproducible sample:

// Need DIRECT_MESSAGES intent
// Need Channel partial
const channel = await client.users.createDM("id", { cache: false });
await channel.send("Hello!");

This kind of mimics the behaviour with sharding:

  1. A direct message is received on a shard that is not shard 0
  2. We receive a MESSAGE_CREATE payload on shard 0 (direct messages are sent to shard 0 always). This means the channel is uncached
  3. We grab the bot's message and use the bot as the recipient:

https://github.com/discordjs/discord.js/blob/3407e1eea3c8d5629465553f342ac30ceae27a47/packages/discord.js/src/client/actions/Action.js#L34-L49

ghost commented 1 year ago

We managed to get a reproduction.

Turns out this is a minimal reproducible sample:

// Need DIRECT_MESSAGES intent
// Need Channel partial
const channel = await client.users.createDM("id", { cache: false });
await channel.send("Hello!");

This kind of mimics the behaviour with sharding:

  1. A direct message is received on a shard that is not shard 0
  2. We receive a MESSAGE_CREATE payload on shard 0 (direct messages are sent to shard 0 always). This means the channel is uncached
  3. We grab the bot's message and use the bot as the recipient:

https://github.com/discordjs/discord.js/blob/3407e1eea3c8d5629465553f342ac30ceae27a47/packages/discord.js/src/client/actions/Action.js#L34-L49

Nice, Thanks for your hard work <3