Skip to content

Issues with partial entities.

Created by: Neuheit

Summary

While DSharpPlus makes things simple by using a single class for many operations, it also creates several challenges for users wanting to do more with a partial entity.

Details

An example of this was reported yesterday by box of kittens (acw)#5184 on Discord. When calling DiscordRestClient.GetGuildAsync(), it returned a DiscordGuild object, and when trying to call GetMemberAsync() on this guild, it threw a NullReferenceException. The reason was because the internal _members dictionary was null, as the API does not return a member list for a guild obtained through rest. Overall, because of these singular entities, users believe they can interact with rest entities like they can with the gateway, which is misleading.

This can also be applied to skeleton entities, or discord objects containing only an Id.

Steps to Reproduce

  1. Create a DiscordRestClient and call GetGuildAsync() with a valid Id.
  2. Try to call GetMemberAsync() on the returned guild.
  3. Observe that a null reference exception is thrown because the internal members cache is null.

Solutions

There are a couple of ways to solve this.

The first is to go through and place null checks on these methods or make sure these object's properties are initialized when used internally in the methods.

The second is to create multiple entities depending on what properties are serialized, similar to Discord.Net. The biggest example would probably be separating rest entities from gateway entities, creating partial object classes as properties (as mentioned in #582), or just exposing the raw ids rather than skeleton objects if the full object cannot be found (as mentioned with MessageReferences in #472).