private async Task HandeCommandRequestException(CommandRequest request, Exception ex) { var ctx = request.Ctx; var guildId = ctx.Guild.Id; var channelId = ctx.Channel.Id; var botChannelId = await _guildSettingsService.GetBotChannelId(guildId); var isCommandInBotChannel = botChannelId != null && botChannelId.Value == channelId; if (isCommandInBotChannel) { await ctx.RespondAsync(ex.Message); } else { await ctx.Message.CreateReactionAsync(DiscordEmoji.FromUnicode(EmojiMap.RedX)); } await _discordErrorLogger.LogDiscordError(ctx, ex.ToString()); _logger.LogError(ex, nameof(HandeCommandRequestException)); }
/// <summary> /// Try to find a suitable error message to return to the user /// if command was executed in a bot channel, otherwise add a reaction. /// Log error to discord logger /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// <returns></returns> private async Task OnCommandErrored(CommandsNextExtension sender, CommandErrorEventArgs e) { var ctx = e.Context; var guildId = ctx.Guild.Id; var channelId = ctx.Channel.Id; var message = ctx.Message; var exception = e.Exception; var commandPrefix = _options.CommandPrefix; var commandHelpText = $"Type \"{commandPrefix}help\" to get some help."; string errorMessage = string.Empty; // Flag unknown commands and not return any error message in this case // as it's easy for users to accidentally trigger commands using the prefix bool isUnknownCommand = false; bool appendHelpText = false; const string unknownSubcommandErrorString = "No matching subcommands were found, and this group is not executable."; const string unknownOverloadErrorString = "Could not find a suitable overload for the command."; var isChecksFailedException = exception is ChecksFailedException; var isUnknownCommandException = exception is CommandNotFoundException; var isUnknownSubcommandException = exception.Message == unknownSubcommandErrorString; var isUnknownOverloadException = exception.Message == unknownOverloadErrorString; var isCommandConfigException = exception is DuplicateCommandException || exception is DuplicateOverloadException || exception is InvalidOverloadException; // TODO: If this isn't enough, create a custom exception class for validation errors var isPossiblyValidationException = exception is ArgumentException; if (isUnknownCommandException) { errorMessage = $"I do not recognize your command."; isUnknownCommand = true; appendHelpText = true; } else if (isUnknownSubcommandException) { errorMessage = $"I do not recognize your command."; appendHelpText = true; } else if (isUnknownOverloadException) { errorMessage = $"Command arguments are (probably) incorrect."; appendHelpText = true; } else if (isCommandConfigException) { errorMessage = $"Something's not quite right."; appendHelpText = true; } else if (isChecksFailedException) { var checksFailedException = (ChecksFailedException)exception; var failedCheck = checksFailedException.FailedChecks[0]; if (failedCheck is BaseCommandCheck) { errorMessage = "I do not care for DM commands."; } else if (failedCheck is RequireOwnerOrFriend) { errorMessage = "You do not have permission to do that."; } else if (failedCheck is CooldownAttribute cooldDownAttribute) { errorMessage = $"Please wait {cooldDownAttribute.Reset.TotalSeconds} seconds"; } else { errorMessage = "Preexecution check failed."; } } else if (isPossiblyValidationException) { errorMessage = $"{exception.Message}."; appendHelpText = true; } var botChannelId = await _guildSettingsService.GetBotChannelId(guildId); var isCommandInBotChannel = botChannelId != null && botChannelId.Value == channelId; if (isCommandInBotChannel) { if (string.IsNullOrWhiteSpace(errorMessage)) { errorMessage = "Something went wrong."; } if (appendHelpText) { errorMessage += $" {commandHelpText}"; } await message.RespondAsync(errorMessage); } else { if (!isUnknownCommand) { await ctx.Message.CreateReactionAsync(DiscordEmoji.FromUnicode(EmojiMap.RedX)); } } // Log any unhandled exception var shouldLogDiscordError = !isUnknownCommandException && !isUnknownSubcommandException && !isCommandConfigException && !isChecksFailedException && !isPossiblyValidationException; if (shouldLogDiscordError) { await _discordErrorLogger.LogDiscordError(ctx, exception.ToString()); } _logger.LogWarning($"Message: {message.Content}\r\nCommand failed: {exception})"); }