public async Task <bool> TryExecuteCommandAsync(SocketUserMessage userMessage) { if (userMessage.Source != MessageSource.User || string.IsNullOrWhiteSpace(userMessage.Content)) { return(false); } var prefixes = new List <string> { _config.DefaultPrefix, $"<@{_client.CurrentUser.Id}> ", $"<@!{_client.CurrentUser.Id}> " }; LocalizedLanguage language; using (var ctx = new AdminDatabaseContext(_provider)) { if (userMessage.Channel is IGuildChannel guildChannel) { var guild = await ctx.GetOrCreateGuildAsync(guildChannel.GuildId); prefixes.AddRange(guild.CustomPrefixes); language = guild.Language; } else { var user = await ctx.GetOrCreateGlobalUserAsync(userMessage.Author.Id); language = user.Language; } } if (!CommandUtilities.HasAnyPrefix(userMessage.Content, prefixes, StringComparison.OrdinalIgnoreCase, out var prefix, out var input)) { return(false); } var context = new AdminCommandContext(userMessage, prefix, language, _provider); var result = await _commands.ExecuteAsync(input, context, _provider); if (!(result is FailedResult failedResult)) { return(true); } // TODO: localized error messages, log var error = new StringBuilder() .Append(failedResult switch { ParameterChecksFailedResult parameterChecksResult => string.Join('\n', parameterChecksResult.FailedChecks.Select(x => x.Error)), ChecksFailedResult checkResult => string.Join('\n', checkResult.FailedChecks.Select(x => x.Error)), ExecutionFailedResult execResult => GenerateException(execResult.Exception), CommandNotFoundResult _ => string.Empty, _ => failedResult.Reason }).ToString();
/// <summary> /// This event is being invoked when the excecuted of a command threw an exception. /// Error results are handled by the result of CommandService#ExecuteAsync. /// </summary> /// <param name="result">Result with its associated exception.</param> /// <param name="context">It represents the context. Must be casted to our custom context (SaltyCommandContext)</param> /// <returns></returns> private Task _commands_CommandErrored(ExecutionFailedResult result, ICommandContext context, IServiceProvider services) { switch (result.Exception) { default: _logger.Debug($"{result.Exception.GetType()} occured.\nError message: {result.Exception.Message}.\nStack trace: {result.Exception.StackTrace}"); break; } return(Task.CompletedTask); }
private async Task OnCommandFailureAsync(CommandFailedEventArgs args) { var reason = args.Result switch { CommandNotFoundResult _ => "Unknown command.", ChecksFailedResult cfr => cfr.FailureReason, ParameterChecksFailedResult pcfr => $"One or more checks failed on parameter **{pcfr.Parameter.Name}**: ```css\n{pcfr.FailedChecks.Select(x => x.Result.FailureReason).Join('\n')}```", ArgumentParseFailedResult apfr => $"Parsing for arguments failed for **{apfr.Command}**.", TypeParseFailedResult tpfr => tpfr.FailureReason, OverloadsFailedResult _ => "A suitable overload could not be found for the given parameter type/order.", ExecutionFailedResult efr => ExecutionFailed(efr), _ => Unknown(args.Result) }; string Unknown(FailedResult result) { _logger.Verbose(LogSource.Service, $"A command returned an unknown error. Please screenshot this message and show it to my developers: {result.GetType().Name}"); return("Unknown error."); } string ExecutionFailed(ExecutionFailedResult result) { _logger.Exception(result.Exception); return($"Execution of this command failed. Exception: {result.Exception.GetType()}"); } if (!reason.IsNullOrEmpty()) { await args.Context.CreateEmbedBuilder() .AddField("Error in Command", args.Context.Command.Name) .AddField("Error Reason", reason) .AddField("Correct Usage", args.Context.Command.GetUsage(args.Context)) .WithErrorColor() .SendToAsync(args.Context.Channel); if (!Config.LogAllCommands) { return; } _logger.Error(LogSource.Module, new StringBuilder() .AppendLine(CommandFrom(args)) .AppendLine(CommandIssued(args)) .AppendLine(ArgsPassed(args)) .AppendLine(InGuild(args)) .AppendLine(InChannel(args)) .AppendLine(TimeIssued(args)) .AppendLine(args.ExecutedLogMessage(reason)) .AppendLine(After(args)) .Append(_separator).ToString()); } }
private async Task OnCommandErrored(ExecutionFailedResult result, ICommandContext context, IServiceProvider services) { if (!(context is FoxCommandContext ctx)) { return; } var str = new StringBuilder(); switch (result.Exception) { case FoxException ex: str.AppendLine(ex.Message); break; case UnauthorizedException _: str.AppendLine("I don't have enough power to perform this action. (please check the hierarchy of the bot is correct)"); break; case BadRequestException _: str.AppendLine("The requested action has been stopped by Discord."); break; case ArgumentException ex: str.AppendLine($"{ex.Message}\n"); str.AppendLine($"You sure you didn't fail the command? Please do `{ctx.Prefix}help {result.Command.FullAliases[0]}`"); break; default: _logger.Print(LogLevel.Error, "Fox", $"{result.Exception.GetType()} occured. Error message: {result.Exception.Message} Stack trace:\n{result.Exception.StackTrace}"); break; } if (str.Length == 0) { return; } var embed = new DiscordEmbedBuilder { Color = ConfigurationService.EmbedColor, Title = "Something went wrong!" }; embed.AddField(Formatter.Underline("Command"), result.Command.Name, true); embed.AddField(Formatter.Underline("Author"), ctx.User.FormatUser(), true); embed.AddField(Formatter.Underline("Error(s)"), str.ToString()); embed.WithFooter($"Type '{ctx.Prefix}help {ctx.Command.FullAliases[0].ToLowerInvariant()}' for more information."); await ctx.RespondAsync("", false, embed); }
private async Task OnCommandFailureAsync(CommandFailedEventArgs args) { FailedCommandCalls += 1; var reason = args.Result switch { CommandNotFoundResult _ => "Unknown command.", ExecutionFailedResult efr => $"Execution of this command failed. Exception: {efr.Exception.GetType()}", ChecksFailedResult cfr => cfr.Reason, ParameterChecksFailedResult pcfr => $"One or more checks failed on parameter **{pcfr.Parameter.Name}**: ```css\n{pcfr.FailedChecks.Select(x => x.Result.Reason).Join('\n')}```", ArgumentParseFailedResult apfr => $"Parsing for arguments failed for **{apfr.Command}**.", TypeParseFailedResult tpfr => tpfr.Reason, OverloadsFailedResult _ => "A suitable overload could not be found for the given parameter type/order.", _ => "Unknown error." }; if (args.Result is ExecutionFailedResult e) { _logger.Exception(e.Exception); } if (!(args.Result is ChecksFailedResult) && !reason.IsNullOrEmpty()) { await args.Context.CreateEmbedBuilder() .AddField("Error in Command", args.Context.Command.Name) .AddField("Error Reason", reason) .AddField("Correct Usage", args.Context.Command.GetUsage(args.Context)) .WithErrorColor() .SendToAsync(args.Context.Channel); if (!Config.LogAllCommands) { return; } Executor.Execute(() => { _logger.Error(LogSource.Module, new StringBuilder() .AppendLine($"| -Command from user: {args.Context.User} ({args.Context.User.Id})") //yes, the spaces in front of each string are indeed intentional on all lines after this .AppendLine($" | -Command Issued: {args.Context.Command.Name}") .AppendLine($" | -Args Passed: {args.Arguments.Trim()}") .AppendLine($" | -In Guild: {args.Context.Guild.Name} ({args.Context.Guild.Id})") .AppendLine($" | -In Channel: #{args.Context.Channel.Name} ({args.Context.Channel.Id})") .AppendLine($" | -Time Issued: {args.Context.Now.FormatFullTime()}, {args.Context.Now.FormatDate()}") .AppendLine($" | -Executed: {args.Result.IsSuccessful} | Reason: {reason}") .AppendLine($" | -After: {args.Stopwatch.Elapsed.Humanize()}") .Append(" -------------------------------------------------").ToString()); }); } }
public async Task OnCommandErroredAsync(ExecutionFailedResult result, ICommandContext originalContext, IServiceProvider _) { if (!(originalContext is GuildContext context)) { return; } if (!string.IsNullOrWhiteSpace(result.Exception.ToString())) { await _log.LogMessage(new LogMessage(LogSeverity.Error, "Command", string.Empty, result.Exception)); (_client.GetChannel(_support.ChannelId) as SocketTextChannel)?.SendMessageAsync($"**Command**: {context.Message}\n**Reason**: {result.Reason}\n**Exception**: ```\n{result.Exception.Message}\n{result.Exception.TargetSite}\n```"); await context.Channel.SendMessageAsync("Hey ya nerd! You broke me! I'll pass this along so it can be looked into. Don't let it happen again..."); } }
public async Task CommandErroredAsync(ExecutionFailedResult result, ICommandContext originalContext, IServiceProvider _) { if (!(originalContext is GuildContext context)) { return; } if (!string.IsNullOrWhiteSpace(result.Exception.ToString())) { await _log.LogMessage(new LogMessage(LogSeverity.Error, "Command", string.Empty, result.Exception)); (_client.GetChannel((await _database.BotConfigs.AsNoTracking().FirstAsync()).SupportChannel) as SocketTextChannel)?.SendMessageAsync("**Guild**: " + context.Guild.Name + " (" + context.Guild.Id + ")\n" + "**Channel**: " + context.Channel.Name + "(" + context.Channel.Id + ")\n**Command**: " + context.Message + " \n**Reason**: " + result.Reason + "\n" + "**Exception**: ```" + result.Exception.Message + "\n" + result.Exception.TargetSite + "```"); await context.Channel.SendMessageAsync(EmoteHelper.Cross + " I'm no beast of burden. *There was an error running the command and has been logged*"); } }
private async Task HandleCommandErrorAsync(ExecutionFailedResult result, ICommandContext context0, IServiceProvider provider) { if (result.IsSuccessful) { return; // Theoretically shouldn't ever happen? } var context = context0.Cast <LittleBigBotExecutionContext>(); var command = result.Command; var exception = result.Exception; var embed = new EmbedBuilder { Color = Color.Red, Title = $"Command '{command.Name}' failed to run.", Description = result.Reason, ThumbnailUrl = context.Bot.GetEffectiveAvatarUrl(), Fields = new List <EmbedFieldBuilder> { new EmbedFieldBuilder { Name = "Message", Value = exception.Message, IsInline = true } }, Footer = new EmbedFooterBuilder { Text = $"If you believe this error is not because of your input, please contact {(await _client.GetApplicationInfoAsync()).Owner}!" } }; _commandsTracking.LogError(exception, context.FormatString(command) + " == DETAILS WILL FOLLOW =="); LogCommandGeneralFailure(context, command, result); await context.Channel.SendMessageAsync(string.Empty, false, embed.Build()); }
private Task CommandServiceOnCommandErrored(ExecutionFailedResult result, ICommandContext context, IServiceProvider provider) { Console.WriteLine($"Command failed: {result.Command.Name} - Reason: {result.Reason}"); return(Task.CompletedTask); }