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;
///
/// Handles error logging for slash command groups.
///
[UsedImplicitly]
public class ErrorLoggingPostExecutionEvent : IPostExecutionEvent
{
private readonly ILogger _logger;
private readonly FeedbackService _feedback;
private readonly IDiscordRestUserAPI _userApi;
public ErrorLoggingPostExecutionEvent(ILogger logger, FeedbackService feedback,
IDiscordRestUserAPI userApi)
{
_logger = logger;
_feedback = feedback;
_userApi = userApi;
}
///
/// Logs a warning using the injected if the has not
/// succeeded.
///
/// The context of the slash command.
/// The result whose success is checked.
/// The cancellation token for this operation. Unused.
/// A result which has succeeded.
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}.");
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);
}
}