From fb3aebb1e0a4b856e5f19b01e0039e3383b21c56 Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Thu, 26 Oct 2023 19:54:15 +0500 Subject: [PATCH] Notify user when a command execution error occurs (#171) With this PR, whenever command execution fails, the user will get an error message with details of the error that can be passed on to developers An unrelated minor change: errors caused by task cancellations will no longer be logged --------- Signed-off-by: Octol1ttle Signed-off-by: mctaylors --- locale/Messages.resx | 6 +++ locale/Messages.ru.resx | 6 +++ locale/Messages.tt-ru.resx | 6 +++ .../Events/ErrorLoggingPostExecutionEvent.cs | 38 +++++++++++++++++-- src/Extensions/LoggerExtensions.cs | 5 +++ src/Messages.Designer.cs | 16 ++++++++ 6 files changed, 74 insertions(+), 3 deletions(-) diff --git a/locale/Messages.resx b/locale/Messages.resx index 0a072c3..5e24811 100644 --- a/locale/Messages.resx +++ b/locale/Messages.resx @@ -570,4 +570,10 @@ Cleared {0} messages from {1} + + An error occurred during command execution, try again later. + + + Contact the developers if the problem occurs again. + diff --git a/locale/Messages.ru.resx b/locale/Messages.ru.resx index 92d4c60..1cc1f9e 100644 --- a/locale/Messages.ru.resx +++ b/locale/Messages.ru.resx @@ -570,4 +570,10 @@ Очищено {0} сообщений от {1} + + Произошла ошибка при выполнении команды, повтори попытку позже. + + + Обратись к разработчикам, если проблема возникнет снова. + diff --git a/locale/Messages.tt-ru.resx b/locale/Messages.tt-ru.resx index 9c5d487..48ad8e7 100644 --- a/locale/Messages.tt-ru.resx +++ b/locale/Messages.tt-ru.resx @@ -570,4 +570,10 @@ вырезано {0} забавных сообщений от {1} + + произошёл тотальный разнос в команде, удачи. + + + если ты это читаешь второй раз за сегодня, пиши разрабам + diff --git a/src/Commands/Events/ErrorLoggingPostExecutionEvent.cs b/src/Commands/Events/ErrorLoggingPostExecutionEvent.cs index d6a66cc..a6daaf0 100644 --- a/src/Commands/Events/ErrorLoggingPostExecutionEvent.cs +++ b/src/Commands/Events/ErrorLoggingPostExecutionEvent.cs @@ -1,8 +1,12 @@ using JetBrains.Annotations; using Microsoft.Extensions.Logging; using Octobot.Extensions; +using Remora.Discord.API.Abstractions.Rest; using Remora.Discord.Commands.Contexts; +using Remora.Discord.Commands.Feedback.Services; using Remora.Discord.Commands.Services; +using Remora.Discord.Extensions.Embeds; +using Remora.Discord.Extensions.Formatting; using Remora.Results; namespace Octobot.Commands.Events; @@ -14,10 +18,15 @@ namespace Octobot.Commands.Events; public class ErrorLoggingPostExecutionEvent : IPostExecutionEvent { private readonly ILogger _logger; + private readonly FeedbackService _feedback; + private readonly IDiscordRestUserAPI _userApi; - public ErrorLoggingPostExecutionEvent(ILogger logger) + public ErrorLoggingPostExecutionEvent(ILogger logger, FeedbackService feedback, + IDiscordRestUserAPI userApi) { _logger = logger; + _feedback = feedback; + _userApi = userApi; } /// @@ -28,11 +37,34 @@ public class ErrorLoggingPostExecutionEvent : IPostExecutionEvent /// The result whose success is checked. /// The cancellation token for this operation. Unused. /// A result which has succeeded. - public Task AfterExecutionAsync( + public async Task AfterExecutionAsync( ICommandContext context, IResult commandResult, CancellationToken ct = default) { _logger.LogResult(commandResult, $"Error in slash command execution for /{context.Command.Command.Node.Key}."); - return Task.FromResult(Result.FromSuccess()); + var result = commandResult; + while (result.Inner is not null) + { + result = result.Inner; + } + + if (result.IsSuccess) + { + return Result.FromSuccess(); + } + + var botResult = await _userApi.GetCurrentUserAsync(ct); + if (!botResult.IsDefined(out var bot)) + { + return Result.FromError(botResult); + } + + var embed = new EmbedBuilder().WithSmallTitle(Messages.CommandExecutionFailed, bot) + .WithDescription(Markdown.InlineCode(result.Error.Message)) + .WithFooter(Messages.ContactDevelopers) + .WithColour(ColorsList.Red) + .Build(); + + return await _feedback.SendContextualEmbedResultAsync(embed, ct); } } diff --git a/src/Extensions/LoggerExtensions.cs b/src/Extensions/LoggerExtensions.cs index fd4aeb7..3805cea 100644 --- a/src/Extensions/LoggerExtensions.cs +++ b/src/Extensions/LoggerExtensions.cs @@ -26,6 +26,11 @@ public static class LoggerExtensions if (result.Error is ExceptionError exe) { + if (exe.Exception is TaskCanceledException) + { + return; + } + logger.LogError(exe.Exception, "{ErrorMessage}", message); return; } diff --git a/src/Messages.Designer.cs b/src/Messages.Designer.cs index 898528c..5f38061 100644 --- a/src/Messages.Designer.cs +++ b/src/Messages.Designer.cs @@ -996,5 +996,21 @@ namespace Octobot { return ResourceManager.GetString("MessagesClearedFiltered", resourceCulture); } } + + internal static string CommandExecutionFailed + { + get + { + return ResourceManager.GetString("CommandExecutionFailed", resourceCulture); + } + } + + internal static string ContactDevelopers + { + get + { + return ResourceManager.GetString("ContactDevelopers", resourceCulture); + } + } } }