예제 #1
0
        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})");
        }