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 <l1ttleofficial@outlook.com>
This commit is contained in:
Octol1ttle 2023-07-28 21:58:55 +05:00 committed by GitHub
parent a6df26af67
commit f47ebe81c5
Signed by: GitHub
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 34 additions and 45 deletions

View file

@ -50,8 +50,7 @@ public class AboutCommandGroup : CommandGroup {
[UsedImplicitly]
public async Task<Result> 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))

View file

@ -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))

View file

@ -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);

View file

@ -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))

View file

@ -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);

View file

@ -53,8 +53,7 @@ public class PingCommandGroup : CommandGroup {
[UsedImplicitly]
public async Task<Result> 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))

View file

@ -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))

View file

@ -71,8 +71,7 @@ public class SettingsCommandGroup : CommandGroup {
public async Task<Result> 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))

View file

@ -12,7 +12,7 @@ public class BoolOption : Option<bool> {
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();

View file

@ -29,6 +29,6 @@ public class LanguageOption : Option<CultureInfo> {
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);
}
}

View file

@ -20,7 +20,7 @@ public partial class SnowflakeOption : Option<Snowflake> {
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();

View file

@ -16,7 +16,7 @@ public class TimeSpanOption : Option<TimeSpan> {
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();

View file

@ -26,7 +26,7 @@ public class InteractionResponders : InteractionGroup {
[Button("scheduled-event-details")]
[UsedImplicitly]
public async Task<Result> 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(

View file

@ -29,7 +29,7 @@ public class GuildMemberJoinedResponder : IResponder<IGuildMemberAdd> {
public async Task<Result> 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()

View file

@ -45,9 +45,9 @@ public class MessageEditedResponder : IResponder<IMessageUpdate> {
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<IMessage>(

View file

@ -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<Result> 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<string> 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<string>.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<string> embedDescription;
if (!scheduledEvent.EntityMetadata.AsOptional().IsDefined(out var metadata))
return Result<string>.FromError(new ArgumentNullError(nameof(scheduledEvent.EntityMetadata)));
return new ArgumentNullError(nameof(scheduledEvent.EntityMetadata));
if (!scheduledEvent.ScheduledEndTime.AsOptional().IsDefined(out var endTime))
return Result<string>.FromError(new ArgumentNullError(nameof(scheduledEvent.ScheduledEndTime)));
return new ArgumentNullError(nameof(scheduledEvent.ScheduledEndTime));
if (!metadata.Location.IsDefined(out var location))
return Result<string>.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<string> GetLocalEventCreatedEmbedDescription(
IGuildScheduledEvent scheduledEvent, string eventDescription) {
if (!scheduledEvent.ChannelID.AsOptional().IsDefined(out var channelId))
return Result<string>.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<string>.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<string> GetLocalEventStartedEmbedDescription(IGuildScheduledEvent scheduledEvent) {
Result<string> embedDescription;
if (!scheduledEvent.ChannelID.AsOptional().IsDefined(out var channelId))
return Result<string>.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<string> GetExternalEventStartedEmbedDescription(IGuildScheduledEvent scheduledEvent) {
Result<string> embedDescription;
if (!scheduledEvent.EntityMetadata.AsOptional().IsDefined(out var metadata))
return Result<string>.FromError(new ArgumentNullError(nameof(scheduledEvent.EntityMetadata)));
return new ArgumentNullError(nameof(scheduledEvent.EntityMetadata));
if (!scheduledEvent.ScheduledEndTime.AsOptional().IsDefined(out var endTime))
return Result<string>.FromError(new ArgumentNullError(nameof(scheduledEvent.ScheduledEndTime)));
return new ArgumentNullError(nameof(scheduledEvent.ScheduledEndTime));
if (!metadata.Location.IsDefined(out var location))
return Result<string>.FromError(new ArgumentNullError(nameof(metadata.Location)));
return new ArgumentNullError(nameof(metadata.Location));
embedDescription = string.Format(
Messages.DescriptionExternalEventStarted,

View file

@ -92,9 +92,9 @@ public class UtilityService : IHostedService {
string action, IGuild guild, IReadOnlyList<IRole> roles, IGuildMember targetMember, IGuildMember currentMember,
IGuildMember interacter) {
if (!targetMember.User.IsDefined(out var targetUser))
return Result<string?>.FromError(new ArgumentNullError(nameof(targetMember.User)));
return new ArgumentNullError(nameof(targetMember.User));
if (!interacter.User.IsDefined(out var interacterUser))
return Result<string?>.FromError(new ArgumentNullError(nameof(interacter.User)));
return new ArgumentNullError(nameof(interacter.User));
if (currentMember.User == targetMember.User)
return Result<string?>.FromSuccess($"UserCannot{action}Bot".Localized());