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
- Create a DiscordRestClient and call
GetGuildAsync()
with a valid Id. - Try to call
GetMemberAsync()
on the returned guild. - 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).