diff --git a/X10D.DSharpPlus/src/DiscordGuildExtensions.cs b/X10D.DSharpPlus/src/DiscordGuildExtensions.cs index 7519bfa..c03016b 100644 --- a/X10D.DSharpPlus/src/DiscordGuildExtensions.cs +++ b/X10D.DSharpPlus/src/DiscordGuildExtensions.cs @@ -1,5 +1,6 @@ using DSharpPlus; using DSharpPlus.Entities; +using DSharpPlus.Exceptions; namespace X10D.DSharpPlus; @@ -27,6 +28,39 @@ public static class DiscordGuildExtensions await Task.WhenAll(guild.Threads.Values.Select(t => t.JoinThreadAsync())).ConfigureAwait(false); } + /// + /// Gets a guild member by their ID. If the member is not found, is returned instead of + /// being thrown. + /// + /// The guild whose member list to search. + /// The ID of the member to retrieve. + /// is . + public static async Task GetMemberOrNullAsync(this DiscordGuild guild, ulong userId) + { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(guild); +#else + if (guild is null) + { + throw new ArgumentNullException(nameof(guild)); + } +#endif + + try + { + // we should never use exceptions for flow control but this is D#+ we're talking about. + // NotFoundException isn't even documented, and yet it gets thrown when a member doesn't exist. + // so this method should hopefully clearly express that - and at least using exceptions for flow control *here*, + // removes the need to do the same in consumer code. + // god I hate this. + return await guild.GetMemberAsync(userId).ConfigureAwait(false); + } + catch (NotFoundException) + { + return null; + } + } + /// /// Normalizes a so that the internal client is assured to be a specified value. ///