From f47ebe81c573a4b4cbd14c3c4b1561d0b0e4b90c Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Fri, 28 Jul 2023 21:58:55 +0500 Subject: [PATCH] Do not wrap result errors when returning them (#73) This PR removes the wrapping of in-house created result errors with `Result.FromError` (I did not know this was possible until today, lol), which reduces code verbosity and makes it easier to read, and replaces `ArgumentNullError` with `ArgumentInvalidError` when retrieving IDs from a command context, which, in my opinion, is more correct. --------- Signed-off-by: Octol1ttle --- src/Commands/AboutCommandGroup.cs | 3 +-- src/Commands/BanCommandGroup.cs | 6 ++--- src/Commands/ClearCommandGroup.cs | 3 +-- src/Commands/KickCommandGroup.cs | 3 +-- src/Commands/MuteCommandGroup.cs | 6 ++--- src/Commands/PingCommandGroup.cs | 3 +-- src/Commands/RemindCommandGroup.cs | 3 +-- src/Commands/SettingsCommandGroup.cs | 6 ++--- src/Data/Options/BoolOption.cs | 2 +- src/Data/Options/LanguageOption.cs | 2 +- src/Data/Options/SnowflakeOption.cs | 2 +- src/Data/Options/TimeSpanOption.cs | 2 +- src/InteractionResponders.cs | 2 +- src/Responders/GuildMemberJoinedResponder.cs | 2 +- src/Responders/MessageEditedResponder.cs | 4 +-- src/Services/GuildUpdateService.cs | 26 ++++++++++---------- src/Services/UtilityService.cs | 4 +-- 17 files changed, 34 insertions(+), 45 deletions(-) diff --git a/src/Commands/AboutCommandGroup.cs b/src/Commands/AboutCommandGroup.cs index b479764..a41cf11 100644 --- a/src/Commands/AboutCommandGroup.cs +++ b/src/Commands/AboutCommandGroup.cs @@ -50,8 +50,7 @@ public class AboutCommandGroup : CommandGroup { [UsedImplicitly] public async Task ExecuteAboutAsync() { if (!_context.TryGetContextIDs(out var guildId, out _, out _)) - return Result.FromError( - new ArgumentNullError(nameof(_context), "Unable to retrieve necessary IDs from command context")); + return new ArgumentInvalidError(nameof(_context), "Unable to retrieve necessary IDs from command context"); var currentUserResult = await _userApi.GetCurrentUserAsync(CancellationToken); if (!currentUserResult.IsDefined(out var currentUser)) diff --git a/src/Commands/BanCommandGroup.cs b/src/Commands/BanCommandGroup.cs index ad5ad5d..465f8d1 100644 --- a/src/Commands/BanCommandGroup.cs +++ b/src/Commands/BanCommandGroup.cs @@ -71,8 +71,7 @@ public class BanCommandGroup : CommandGroup { [Description("Ban reason")] string reason, [Description("Ban duration")] TimeSpan? duration = null) { if (!_context.TryGetContextIDs(out var guildId, out var channelId, out var userId)) - return Result.FromError( - new ArgumentNullError(nameof(_context), "Unable to retrieve necessary IDs from command context")); + return new ArgumentInvalidError(nameof(_context), "Unable to retrieve necessary IDs from command context"); // The current user's avatar is used when sending error messages var currentUserResult = await _userApi.GetCurrentUserAsync(CancellationToken); if (!currentUserResult.IsDefined(out var currentUser)) @@ -186,8 +185,7 @@ public class BanCommandGroup : CommandGroup { [Description("User to unban")] IUser target, [Description("Unban reason")] string reason) { if (!_context.TryGetContextIDs(out var guildId, out var channelId, out var userId)) - return Result.FromError( - new ArgumentNullError(nameof(_context), "Unable to retrieve necessary IDs from command context")); + return new ArgumentInvalidError(nameof(_context), "Unable to retrieve necessary IDs from command context"); // The current user's avatar is used when sending error messages var currentUserResult = await _userApi.GetCurrentUserAsync(CancellationToken); if (!currentUserResult.IsDefined(out var currentUser)) diff --git a/src/Commands/ClearCommandGroup.cs b/src/Commands/ClearCommandGroup.cs index 9fae93c..0c241e3 100644 --- a/src/Commands/ClearCommandGroup.cs +++ b/src/Commands/ClearCommandGroup.cs @@ -61,8 +61,7 @@ public class ClearCommandGroup : CommandGroup { [Description("Number of messages to remove (2-100)")] [MinValue(2)] [MaxValue(100)] int amount) { if (!_context.TryGetContextIDs(out var guildId, out var channelId, out var userId)) - return Result.FromError( - new ArgumentNullError(nameof(_context), "Unable to retrieve necessary IDs from command context")); + return new ArgumentInvalidError(nameof(_context), "Unable to retrieve necessary IDs from command context"); var messagesResult = await _channelApi.GetChannelMessagesAsync( channelId, limit: amount + 1, ct: CancellationToken); diff --git a/src/Commands/KickCommandGroup.cs b/src/Commands/KickCommandGroup.cs index 62bbbad..5d7909f 100644 --- a/src/Commands/KickCommandGroup.cs +++ b/src/Commands/KickCommandGroup.cs @@ -66,8 +66,7 @@ public class KickCommandGroup : CommandGroup { [Description("Member to kick")] IUser target, [Description("Kick reason")] string reason) { if (!_context.TryGetContextIDs(out var guildId, out var channelId, out var userId)) - return Result.FromError( - new ArgumentNullError(nameof(_context), "Unable to retrieve necessary IDs from command context")); + return new ArgumentInvalidError(nameof(_context), "Unable to retrieve necessary IDs from command context"); // The current user's avatar is used when sending error messages var currentUserResult = await _userApi.GetCurrentUserAsync(CancellationToken); if (!currentUserResult.IsDefined(out var currentUser)) diff --git a/src/Commands/MuteCommandGroup.cs b/src/Commands/MuteCommandGroup.cs index 697e24e..af967b9 100644 --- a/src/Commands/MuteCommandGroup.cs +++ b/src/Commands/MuteCommandGroup.cs @@ -68,8 +68,7 @@ public class MuteCommandGroup : CommandGroup { [Description("Mute reason")] string reason, [Description("Mute duration")] TimeSpan duration) { if (!_context.TryGetContextIDs(out var guildId, out var channelId, out var userId)) - return Result.FromError( - new ArgumentNullError(nameof(_context), "Unable to retrieve necessary IDs from command context")); + return new ArgumentInvalidError(nameof(_context), "Unable to retrieve necessary IDs from command context"); // The current user's avatar is used when sending error messages var currentUserResult = await _userApi.GetCurrentUserAsync(CancellationToken); @@ -162,8 +161,7 @@ public class MuteCommandGroup : CommandGroup { [Description("Member to unmute")] IUser target, [Description("Unmute reason")] string reason) { if (!_context.TryGetContextIDs(out var guildId, out var channelId, out var userId)) - return Result.FromError( - new ArgumentNullError(nameof(_context), "Unable to retrieve necessary IDs from command context")); + return new ArgumentInvalidError(nameof(_context), "Unable to retrieve necessary IDs from command context"); // The current user's avatar is used when sending error messages var currentUserResult = await _userApi.GetCurrentUserAsync(CancellationToken); diff --git a/src/Commands/PingCommandGroup.cs b/src/Commands/PingCommandGroup.cs index 08e0c58..f301edb 100644 --- a/src/Commands/PingCommandGroup.cs +++ b/src/Commands/PingCommandGroup.cs @@ -53,8 +53,7 @@ public class PingCommandGroup : CommandGroup { [UsedImplicitly] public async Task ExecutePingAsync() { if (!_context.TryGetContextIDs(out var guildId, out var channelId, out _)) - return Result.FromError( - new ArgumentNullError(nameof(_context), "Unable to retrieve necessary IDs from command context")); + return new ArgumentInvalidError(nameof(_context), "Unable to retrieve necessary IDs from command context"); var currentUserResult = await _userApi.GetCurrentUserAsync(CancellationToken); if (!currentUserResult.IsDefined(out var currentUser)) diff --git a/src/Commands/RemindCommandGroup.cs b/src/Commands/RemindCommandGroup.cs index 2d892bc..9734ab5 100644 --- a/src/Commands/RemindCommandGroup.cs +++ b/src/Commands/RemindCommandGroup.cs @@ -52,8 +52,7 @@ public class RemindCommandGroup : CommandGroup { TimeSpan @in, [Description("Reminder message")] string message) { if (!_context.TryGetContextIDs(out var guildId, out var channelId, out var userId)) - return Result.FromError( - new ArgumentNullError(nameof(_context), "Unable to retrieve necessary IDs from command context")); + return new ArgumentInvalidError(nameof(_context), "Unable to retrieve necessary IDs from command context"); var userResult = await _userApi.GetUserAsync(userId, CancellationToken); if (!userResult.IsDefined(out var user)) diff --git a/src/Commands/SettingsCommandGroup.cs b/src/Commands/SettingsCommandGroup.cs index 9bfbc95..5a9efad 100644 --- a/src/Commands/SettingsCommandGroup.cs +++ b/src/Commands/SettingsCommandGroup.cs @@ -71,8 +71,7 @@ public class SettingsCommandGroup : CommandGroup { public async Task ExecuteSettingsListAsync( [Description("Settings list page")] int page) { if (!_context.TryGetContextIDs(out var guildId, out _, out _)) - return Result.FromError( - new ArgumentNullError(nameof(_context), "Unable to retrieve necessary IDs from command context")); + return new ArgumentInvalidError(nameof(_context), "Unable to retrieve necessary IDs from command context"); var currentUserResult = await _userApi.GetCurrentUserAsync(CancellationToken); if (!currentUserResult.IsDefined(out var currentUser)) @@ -142,8 +141,7 @@ public class SettingsCommandGroup : CommandGroup { string setting, [Description("Setting value")] string value) { if (!_context.TryGetContextIDs(out var guildId, out _, out _)) - return Result.FromError( - new ArgumentNullError(nameof(_context), "Unable to retrieve necessary IDs from command context")); + return new ArgumentInvalidError(nameof(_context), "Unable to retrieve necessary IDs from command context"); var currentUserResult = await _userApi.GetCurrentUserAsync(CancellationToken); if (!currentUserResult.IsDefined(out var currentUser)) diff --git a/src/Data/Options/BoolOption.cs b/src/Data/Options/BoolOption.cs index e8be77a..edf6b26 100644 --- a/src/Data/Options/BoolOption.cs +++ b/src/Data/Options/BoolOption.cs @@ -12,7 +12,7 @@ public class BoolOption : Option { public override Result Set(JsonNode settings, string from) { if (!TryParseBool(from, out var value)) - return Result.FromError(new ArgumentInvalidError(nameof(from), Messages.InvalidSettingValue)); + return new ArgumentInvalidError(nameof(from), Messages.InvalidSettingValue); settings[Name] = value; return Result.FromSuccess(); diff --git a/src/Data/Options/LanguageOption.cs b/src/Data/Options/LanguageOption.cs index dbe1b4f..5c50899 100644 --- a/src/Data/Options/LanguageOption.cs +++ b/src/Data/Options/LanguageOption.cs @@ -29,6 +29,6 @@ public class LanguageOption : Option { public override Result Set(JsonNode settings, string from) { return CultureInfoCache.ContainsKey(from.ToLowerInvariant()) ? base.Set(settings, from.ToLowerInvariant()) - : Result.FromError(new ArgumentInvalidError(nameof(from), Messages.LanguageNotSupported)); + : new ArgumentInvalidError(nameof(from), Messages.LanguageNotSupported); } } diff --git a/src/Data/Options/SnowflakeOption.cs b/src/Data/Options/SnowflakeOption.cs index 05921ff..66dfa8c 100644 --- a/src/Data/Options/SnowflakeOption.cs +++ b/src/Data/Options/SnowflakeOption.cs @@ -20,7 +20,7 @@ public partial class SnowflakeOption : Option { public override Result Set(JsonNode settings, string from) { if (!ulong.TryParse(NonNumbers().Replace(from, ""), out var parsed)) - return Result.FromError(new ArgumentInvalidError(nameof(from), Messages.InvalidSettingValue)); + return new ArgumentInvalidError(nameof(from), Messages.InvalidSettingValue); settings[Name] = parsed; return Result.FromSuccess(); diff --git a/src/Data/Options/TimeSpanOption.cs b/src/Data/Options/TimeSpanOption.cs index 659d88c..3aa1fd5 100644 --- a/src/Data/Options/TimeSpanOption.cs +++ b/src/Data/Options/TimeSpanOption.cs @@ -16,7 +16,7 @@ public class TimeSpanOption : Option { public override Result Set(JsonNode settings, string from) { if (!ParseTimeSpan(from).IsDefined(out var span)) - return Result.FromError(new ArgumentInvalidError(nameof(from), Messages.InvalidSettingValue)); + return new ArgumentInvalidError(nameof(from), Messages.InvalidSettingValue); settings[Name] = span.ToString(); return Result.FromSuccess(); diff --git a/src/InteractionResponders.cs b/src/InteractionResponders.cs index 00ef0b2..977f00f 100644 --- a/src/InteractionResponders.cs +++ b/src/InteractionResponders.cs @@ -26,7 +26,7 @@ public class InteractionResponders : InteractionGroup { [Button("scheduled-event-details")] [UsedImplicitly] public async Task OnStatefulButtonClicked(string? state = null) { - if (state is null) return Result.FromError(new ArgumentNullError(nameof(state))); + if (state is null) return new ArgumentNullError(nameof(state)); var idArray = state.Split(':'); return (Result)await _feedbackService.SendContextualAsync( diff --git a/src/Responders/GuildMemberJoinedResponder.cs b/src/Responders/GuildMemberJoinedResponder.cs index c61e500..5357363 100644 --- a/src/Responders/GuildMemberJoinedResponder.cs +++ b/src/Responders/GuildMemberJoinedResponder.cs @@ -29,7 +29,7 @@ public class GuildMemberJoinedResponder : IResponder { public async Task RespondAsync(IGuildMemberAdd gatewayEvent, CancellationToken ct = default) { if (!gatewayEvent.User.IsDefined(out var user)) - return Result.FromError(new ArgumentNullError(nameof(gatewayEvent.User))); + return new ArgumentNullError(nameof(gatewayEvent.User)); var data = await _dataService.GetData(gatewayEvent.GuildID, ct); var cfg = data.Settings; if (GuildSettings.PublicFeedbackChannel.Get(cfg).Empty() diff --git a/src/Responders/MessageEditedResponder.cs b/src/Responders/MessageEditedResponder.cs index 0211170..e7ec215 100644 --- a/src/Responders/MessageEditedResponder.cs +++ b/src/Responders/MessageEditedResponder.cs @@ -45,9 +45,9 @@ public class MessageEditedResponder : IResponder { return Result.FromSuccess(); // The message wasn't actually edited if (!gatewayEvent.ChannelID.IsDefined(out var channelId)) - return Result.FromError(new ArgumentNullError(nameof(gatewayEvent.ChannelID))); + return new ArgumentNullError(nameof(gatewayEvent.ChannelID)); if (!gatewayEvent.ID.IsDefined(out var messageId)) - return Result.FromError(new ArgumentNullError(nameof(gatewayEvent.ID))); + return new ArgumentNullError(nameof(gatewayEvent.ID)); var cacheKey = new KeyHelpers.MessageCacheKey(channelId, messageId); var messageResult = await _cacheService.TryGetValueAsync( diff --git a/src/Services/GuildUpdateService.cs b/src/Services/GuildUpdateService.cs index c743b8e..c5d5659 100644 --- a/src/Services/GuildUpdateService.cs +++ b/src/Services/GuildUpdateService.cs @@ -163,7 +163,7 @@ public partial class GuildUpdateService : BackgroundService { await SendScheduledEventCreatedMessage(scheduledEvent, data.Settings, ct), GuildScheduledEventStatus.Active or GuildScheduledEventStatus.Completed => await SendScheduledEventUpdatedMessage(scheduledEvent, data, ct), - _ => Result.FromError(new ArgumentOutOfRangeError(nameof(scheduledEvent.Status))) + _ => new ArgumentOutOfRangeError(nameof(scheduledEvent.Status)) }; if (!statusChangedResponseResult.IsSuccess) @@ -295,7 +295,7 @@ public partial class GuildUpdateService : BackgroundService { private async Task SendScheduledEventCreatedMessage( IGuildScheduledEvent scheduledEvent, JsonNode settings, CancellationToken ct = default) { if (!scheduledEvent.Creator.IsDefined(out var creator)) - return Result.FromError(new ArgumentNullError(nameof(scheduledEvent.Creator))); + return new ArgumentNullError(nameof(scheduledEvent.Creator)); Result embedDescriptionResult; var eventDescription = scheduledEvent.Description is { HasValue: true, Value: not null } @@ -306,7 +306,7 @@ public partial class GuildUpdateService : BackgroundService { GetLocalEventCreatedEmbedDescription(scheduledEvent, eventDescription), GuildScheduledEventEntityType.External => GetExternalScheduledEventCreatedEmbedDescription( scheduledEvent, eventDescription), - _ => Result.FromError(new ArgumentOutOfRangeError(nameof(scheduledEvent.EntityType))) + _ => new ArgumentOutOfRangeError(nameof(scheduledEvent.EntityType)) }; if (!embedDescriptionResult.IsDefined(out var embedDescription)) @@ -343,11 +343,11 @@ public partial class GuildUpdateService : BackgroundService { IGuildScheduledEvent scheduledEvent, string eventDescription) { Result embedDescription; if (!scheduledEvent.EntityMetadata.AsOptional().IsDefined(out var metadata)) - return Result.FromError(new ArgumentNullError(nameof(scheduledEvent.EntityMetadata))); + return new ArgumentNullError(nameof(scheduledEvent.EntityMetadata)); if (!scheduledEvent.ScheduledEndTime.AsOptional().IsDefined(out var endTime)) - return Result.FromError(new ArgumentNullError(nameof(scheduledEvent.ScheduledEndTime))); + return new ArgumentNullError(nameof(scheduledEvent.ScheduledEndTime)); if (!metadata.Location.IsDefined(out var location)) - return Result.FromError(new ArgumentNullError(nameof(metadata.Location))); + return new ArgumentNullError(nameof(metadata.Location)); embedDescription = $"{eventDescription}\n\n{Markdown.BlockQuote( string.Format( @@ -362,7 +362,7 @@ public partial class GuildUpdateService : BackgroundService { private static Result GetLocalEventCreatedEmbedDescription( IGuildScheduledEvent scheduledEvent, string eventDescription) { if (!scheduledEvent.ChannelID.AsOptional().IsDefined(out var channelId)) - return Result.FromError(new ArgumentNullError(nameof(scheduledEvent.ChannelID))); + return new ArgumentNullError(nameof(scheduledEvent.ChannelID)); return $"{eventDescription}\n\n{Markdown.BlockQuote( string.Format( @@ -390,7 +390,7 @@ public partial class GuildUpdateService : BackgroundService { GuildScheduledEventEntityType.StageInstance or GuildScheduledEventEntityType.Voice => GetLocalEventStartedEmbedDescription(scheduledEvent), GuildScheduledEventEntityType.External => GetExternalEventStartedEmbedDescription(scheduledEvent), - _ => Result.FromError(new ArgumentOutOfRangeError(nameof(scheduledEvent.EntityType))) + _ => new ArgumentOutOfRangeError(nameof(scheduledEvent.EntityType)) }; var contentResult = await _utility.GetEventNotificationMentions( @@ -414,7 +414,7 @@ public partial class GuildUpdateService : BackgroundService { } if (scheduledEvent.Status != GuildScheduledEventStatus.Completed) - return Result.FromError(new ArgumentOutOfRangeError(nameof(scheduledEvent.Status))); + return new ArgumentOutOfRangeError(nameof(scheduledEvent.Status)); data.ScheduledEvents.Remove(scheduledEvent.ID.Value); var completedEmbed = new EmbedBuilder().WithTitle(string.Format(Messages.EventCompleted, scheduledEvent.Name)) @@ -439,7 +439,7 @@ public partial class GuildUpdateService : BackgroundService { private static Result GetLocalEventStartedEmbedDescription(IGuildScheduledEvent scheduledEvent) { Result embedDescription; if (!scheduledEvent.ChannelID.AsOptional().IsDefined(out var channelId)) - return Result.FromError(new ArgumentNullError(nameof(scheduledEvent.ChannelID))); + return new ArgumentNullError(nameof(scheduledEvent.ChannelID)); embedDescription = string.Format( Messages.DescriptionLocalEventStarted, @@ -451,11 +451,11 @@ public partial class GuildUpdateService : BackgroundService { private static Result GetExternalEventStartedEmbedDescription(IGuildScheduledEvent scheduledEvent) { Result embedDescription; if (!scheduledEvent.EntityMetadata.AsOptional().IsDefined(out var metadata)) - return Result.FromError(new ArgumentNullError(nameof(scheduledEvent.EntityMetadata))); + return new ArgumentNullError(nameof(scheduledEvent.EntityMetadata)); if (!scheduledEvent.ScheduledEndTime.AsOptional().IsDefined(out var endTime)) - return Result.FromError(new ArgumentNullError(nameof(scheduledEvent.ScheduledEndTime))); + return new ArgumentNullError(nameof(scheduledEvent.ScheduledEndTime)); if (!metadata.Location.IsDefined(out var location)) - return Result.FromError(new ArgumentNullError(nameof(metadata.Location))); + return new ArgumentNullError(nameof(metadata.Location)); embedDescription = string.Format( Messages.DescriptionExternalEventStarted, diff --git a/src/Services/UtilityService.cs b/src/Services/UtilityService.cs index 6ddc204..21aade1 100644 --- a/src/Services/UtilityService.cs +++ b/src/Services/UtilityService.cs @@ -92,9 +92,9 @@ public class UtilityService : IHostedService { string action, IGuild guild, IReadOnlyList roles, IGuildMember targetMember, IGuildMember currentMember, IGuildMember interacter) { if (!targetMember.User.IsDefined(out var targetUser)) - return Result.FromError(new ArgumentNullError(nameof(targetMember.User))); + return new ArgumentNullError(nameof(targetMember.User)); if (!interacter.User.IsDefined(out var interacterUser)) - return Result.FromError(new ArgumentNullError(nameof(interacter.User))); + return new ArgumentNullError(nameof(interacter.User)); if (currentMember.User == targetMember.User) return Result.FromSuccess($"UserCannot{action}Bot".Localized());