Exemple #1
0
        private async Task Commands_CommandErrored(CommandErrorEventArgs e)
        {
            e.Context.Client.DebugLogger.LogMessage(LogLevel.Error, this.Bot.LogName, $"{e.Context.User.Username} tried executing '{e.Command?.QualifiedName ?? "<unknown command>"}' but it errored: {e.Exception.GetType()}: {e.Exception.Message ?? "<no message>"}", DateTime.Now);


            var ex = e.Exception;

            while (ex is AggregateException || ex.InnerException != null)
            {
                ex = ex.InnerException;
            }

            // Check if exception is result of command prechecks.
            switch (ex)
            {
            case ChecksFailedException exep:
            {
                var failedchecks = exep.FailedChecks.First();
                switch (failedchecks)
                {
                // Bot is lacking permissions.
                case RequireBotPermissionsAttribute reqbotperm:
                {
                    string permissionsLacking = reqbotperm.Permissions.ToPermissionString();
                    var    emoji = DiscordEmoji.FromName(e.Context.Client, ":no_entry:");
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithTitle($"{emoji} Боту не хватает прав")
                                                 .WithDescription(permissionsLacking)).ConfigureAwait(false);

                    break;
                }

                // User is lacking permissions.
                case RequireUserPermissionsAttribute requserperm:
                {
                    string permissionsLacking = requserperm.Permissions.ToPermissionString();
                    var    emoji = DiscordEmoji.FromName(e.Context.Client, ":no_entry:");

                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithTitle($"{emoji} Вам не хватает прав")
                                                 .WithDescription(permissionsLacking)).ConfigureAwait(false);

                    break;
                }

                // User is not owner of the bot.
                case RequireOwnerAttribute reqowner:
                {
                    var emoji = DiscordEmoji.FromName(e.Context.Client, ":no_entry:");
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithTitle($"{emoji} Команда доступна только владельцу")).ConfigureAwait(false);

                    break;
                }

                // User is not owner or don't have permissions.
                case OwnerOrPermissionAttribute ownerOrPermission:
                {
                    string permissionsLacking = ownerOrPermission.Permissions.ToPermissionString();
                    var    emoji = DiscordEmoji.FromName(e.Context.Client, ":no_entry:");
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithTitle($"{emoji} Вы не являетесь владельцем или вам не хватает прав")
                                                 .WithDescription(permissionsLacking)).ConfigureAwait(false);

                    break;
                }

                // Command shouldn't be executed so fast.
                case CooldownAttribute cooldown:
                {
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithDescription("Вы пытаетесь использовать команду слишком часто, таймер - " +
                                                                  $"не больше {cooldown.MaxUses} раз в {cooldown.Reset.TotalMinutes} минут")).ConfigureAwait(false);

                    break;
                }

                // User wasn't connected to voice channel. Optionally to the same voice channel as bot
                case RequireVoiceConnectionAttribute requireVoice:
                {
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithDescription($"Вы должны быть подключены к {(requireVoice.SameVoiceChannelAsBot ? "тому же голосовому каналу что и бот" : "голосовому каналу")}")).ConfigureAwait(false);

                    break;
                }

                default:
                {
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithDescription($"Вам не хватает прав, чтобы узнать каких используйте {Formatter.InlineCode($"{this.Bot.Config.Discord.Prefixes.RandomElement()}help {e.Command.QualifiedName}")}"));

                    break;
                }
                }

                break;
            }

            case DatabaseException dbEx:
            {
                var description = new StringBuilder("Произошла ошибка в работе БД, возможно стоит попробовать чуть позже.");
                description.AppendLine(string.IsNullOrWhiteSpace(dbEx.Message)
                                                ? $"Тип действия: {dbEx.ActionType.ToString()}"
                                                : $"Сообщение - {Formatter.InlineCode(dbEx.Message)}. Тип действия: {dbEx.ActionType.ToString()}");

                await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                             .WithDescription(description.ToString())).ConfigureAwait(false);

                break;
            }

            case DiscordUserInputException inputEx:
            {
                await e.Context.RespondAsync($"{inputEx.Message}. Название параметра {inputEx.ArgumentName}").ConfigureAwait(false);

                break;
            }

            case CommandNotFoundException commandNotFoundException:
            {
                var cmdName           = commandNotFoundException.CommandName;
                var suggestedCommands = new List <Command>();
                var nL = new NormalizedLevenshtein();

                // Let's assumme that 0.33 is good Levenshtein distance

                foreach (var cmd in this.Commands.RegisteredCommands.Values.Distinct())
                {
                    if (cmd is CommandGroup cmdGroup)
                    {
                        foreach (var children in cmdGroup.Children)
                        {
                            if (Helpers.IsCommandSimilar(children, cmdName, nL))
                            {
                                suggestedCommands.Add(children);
                            }
                        }
                        if (cmdGroup.IsExecutableWithoutSubcommands && Helpers.IsCommandSimilar(cmdGroup, cmdName, nL))
                        {
                            suggestedCommands.Add(cmdGroup);
                        }
                    }
                    else
                    {
                        if (Helpers.IsCommandSimilar(cmd, cmdName, nL))
                        {
                            suggestedCommands.Add(cmd);
                        }
                    }
                }

                if (suggestedCommands.Any())
                {
                    suggestedCommands.OrderBy(x => x.QualifiedName);
                    var description = new StringBuilder();
                    description.AppendLine($"Команды с названием {Formatter.InlineCode(cmdName)} не найдено. Вот возможные варианты того, что вы имели в виду:");
                    foreach (var cmd in suggestedCommands)
                    {
                        description.AppendLine(Formatter.InlineCode(cmd.QualifiedName));
                    }

                    await e.Context.RespondAsync(embed : EmbedTemplates.ErrorEmbed()
                                                 .WithDescription(description.ToString())).ConfigureAwait(false);
                }
                break;
            }

            case InvalidOperationException invOpEx when invOpEx.Message == "No matching subcommands were found, and this group is not executable.":
            {
                //Ignore.
                break;
            }

            default:
            {
                var embed = EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                            .WithTitle("Произошла непредвиденная ошибка в работе команды")
                            .WithDescription($"Message: \n{Formatter.InlineCode(ex.Message)}\n в \n{Formatter.InlineCode(ex.Source)}");
                await e.Context.RespondAsync(embed : embed).ConfigureAwait(false);

                await this.Bot.ErrorChannel.SendMessageAsync(embed : embed).ConfigureAwait(false);

                break;
            }
            }
        }