Skip to content

Embed#equals() will never equal EmbedBuilder#data #9095

@Jiralite

Description

@Jiralite

Which package is this bug report for?

discord.js

Issue description

Here is the definition for Embed#equals():

/**
* Whether the given embeds are equal.
* @param {Embed|APIEmbed} other The embed to compare against
* @returns {boolean}
*/
equals(other) {
if (other instanceof Embed) {
return isEqual(other.data, this.data);
}
return isEqual(other, this.data);
}

This may take an APIEmbed. Looking at EmbedBuilder#data:

/**
* Represents a embed in a message (image/video preview, rich embed, etc.)
*/
export class EmbedBuilder {
public readonly data: APIEmbed;

We can see this is an APIEmbed. Therefore, these should be comparable. However, comparisons here will never be equal, as received embeds from Discord have a type property which is not present during construction.

The code sample contains a console.log(), of which the output is:

false { type: 'rich', description: 'test' } { description: 'test' }

The internally-called isEqual() method is derived from fast-deep-equal which compares the number of object keys, thus introducing this bug (view source code here).

An important mention here is that this is not limited to Discord's returned type property. Field inline values are optional whereas Discord will always return them, causing a mismatch of the length of keys. Additionally, what if Discord creates a new property on an embed? As soon as their API deployment is done, this method will begin failing despite no changes in discord.js.

Code sample

import { Client, Events, GatewayIntentBits, EmbedBuilder } from "discord.js";
import { inspect } from "node:util";

const client = new Client({ intents: GatewayIntentBits.Guilds });
const embed = new EmbedBuilder().setDescription("test");

client.on(Events.ClientReady, async () => {
	const channel = client.channels.resolve("channel_id");
	const message = await channel.send({ embeds: [embed] });

	console.log(
		message.embeds[0].equals(embed.data),
		inspect(message.embeds[0].data, false, Number.POSITIVE_INFINITY, true),
		inspect(embed.data, false, Number.POSITIVE_INFINITY, true),
	);
});

client.login();

Package version

14.7.2-dev

Node.js version

Node.js 18.13.0 & typescript 4.9.4

Operating system

macOS Ventura 13.1

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

I have tested this issue on a development release

8b70f49

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions