From 605a5c67bee77f226f4189bc203be3eca2729f1d Mon Sep 17 00:00:00 2001 From: 13xforever Date: Mon, 1 Oct 2018 22:10:43 +0500 Subject: [PATCH] Swallow all exceptions in async void methods Otherwise an uncaught exception will terminate the whole process :( --- CompatBot/Commands/Moderation.Audit.cs | 11 +- CompatBot/EventHandlers/LogInfoHandler.cs | 160 +++++++++++---------- CompatBot/ThumbScrapper/PsnScraper.cs | 5 + CompatBot/Utils/AutosplitResponseHelper.cs | 3 +- 4 files changed, 101 insertions(+), 78 deletions(-) diff --git a/CompatBot/Commands/Moderation.Audit.cs b/CompatBot/Commands/Moderation.Audit.cs index a4fb493f..f2b400ef 100644 --- a/CompatBot/Commands/Moderation.Audit.cs +++ b/CompatBot/Commands/Moderation.Audit.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; @@ -6,6 +7,7 @@ using System.Threading.Tasks; using CompatBot.Commands.Attributes; using CompatBot.EventHandlers; using CompatBot.Utils; +using DSharpPlus; using DSharpPlus.CommandsNext; using DSharpPlus.CommandsNext.Attributes; using DSharpPlus.Entities; @@ -35,6 +37,7 @@ namespace CompatBot.Commands await ctx.RespondAsync("Another check is already in progress").ConfigureAwait(false); return; } + try { await ctx.TriggerTypingAsync().ConfigureAwait(false); @@ -63,6 +66,12 @@ namespace CompatBot.Commands else await ctx.RespondAsync("No potential name spoofing was detected").ConfigureAwait(false); } + catch (Exception e) + { + ctx.Client.DebugLogger.LogMessage(LogLevel.Error, "", e.ToString(), DateTime.Now); + //should be extra careful, as async void will run on a thread pull, and will terminate the whole application with an uncaught exception + try { await ctx.ReactWithAsync(Config.Reactions.Failure, "(X_X)").ConfigureAwait(false); } catch { } + } finally { CheckLock.Release(1); diff --git a/CompatBot/EventHandlers/LogInfoHandler.cs b/CompatBot/EventHandlers/LogInfoHandler.cs index 97cbd192..41e98770 100644 --- a/CompatBot/EventHandlers/LogInfoHandler.cs +++ b/CompatBot/EventHandlers/LogInfoHandler.cs @@ -50,98 +50,106 @@ namespace CompatBot.EventHandlers public static async void BackgroundProcessor(MessageCreateEventArgs args) { - var message = args.Message; - if (!QueueLimiter.Wait(0)) - { - await args.Channel.SendMessageAsync("Log processing is rate limited, try again a bit later").ConfigureAwait(false); - return; - } - - bool parsedLog = false; - var startTime = Stopwatch.StartNew(); try { - foreach (var attachment in message.Attachments.Where(a => a.FileSize < Config.AttachmentSizeLimit)) - foreach (var handler in handlers) - if (await handler.CanHandleAsync(attachment).ConfigureAwait(false)) - { - await args.Channel.TriggerTypingAsync().ConfigureAwait(false); - Console.WriteLine($">>>>>>> {message.Id%100} Parsing log from attachment {attachment.FileName} ({attachment.FileSize})..."); - parsedLog = true; - LogParseState result = null; - try - { - var pipe = new Pipe(); - var fillPipeTask = handler.FillPipeAsync(attachment, pipe.Writer); - result = await LogParser.ReadPipeAsync(pipe.Reader).ConfigureAwait(false); - await fillPipeTask.ConfigureAwait(false); - } - catch (Exception e) - { - args.Client.DebugLogger.LogMessage(LogLevel.Error, "", "Log parsing failed: " + e, DateTime.Now); - } - if (result == null) - await args.Channel.SendMessageAsync("Log analysis failed, most likely cause is a truncated/invalid log. Please run the game again and reupload the new copy.").ConfigureAwait(false); - else + var message = args.Message; + if (!QueueLimiter.Wait(0)) + { + await args.Channel.SendMessageAsync("Log processing is rate limited, try again a bit later").ConfigureAwait(false); + return; + } + + bool parsedLog = false; + var startTime = Stopwatch.StartNew(); + try + { + foreach (var attachment in message.Attachments.Where(a => a.FileSize < Config.AttachmentSizeLimit)) + foreach (var handler in handlers) + if (await handler.CanHandleAsync(attachment).ConfigureAwait(false)) { + await args.Channel.TriggerTypingAsync().ConfigureAwait(false); + Console.WriteLine($">>>>>>> {message.Id % 100} Parsing log from attachment {attachment.FileName} ({attachment.FileSize})..."); + parsedLog = true; + LogParseState result = null; try { - if (result.Error == LogParseState.ErrorCode.PiracyDetected) - { - if (args.Author.IsWhitelisted(args.Client, args.Guild)) - { - await Task.WhenAll( - args.Channel.SendMessageAsync("I see wha' ye did thar ☠"), - args.Client.ReportAsync("Pirated Release (whitelisted by role)", args.Message, result.PiracyTrigger, result.PiracyContext, ReportSeverity.Low) - ).ConfigureAwait(false); - } - else - { - var severity = ReportSeverity.Low; - try - { - await message.DeleteAsync("Piracy detected in log").ConfigureAwait(false); - } - catch (Exception e) - { - severity = ReportSeverity.High; - args.Client.DebugLogger.LogMessage(LogLevel.Warning, "", $"Unable to delete message in {args.Channel.Name}: {e.Message}", DateTime.Now); - } - await args.Channel.SendMessageAsync(embed: await result.AsEmbedAsync(args.Client, args.Message).ConfigureAwait(false)).ConfigureAwait(false); - await Task.WhenAll( - args.Client.ReportAsync("Pirated Release", args.Message, result.PiracyTrigger, result.PiracyContext, severity), - Warnings.AddAsync(args.Client, args.Message, args.Message.Author.Id, args.Message.Author.Username, args.Client.CurrentUser, - "Pirated Release", $"{message.Content.Sanitize()} - {result.PiracyTrigger}") - ); - } - } - else - await args.Channel.SendMessageAsync(embed: await result.AsEmbedAsync(args.Client, args.Message).ConfigureAwait(false)).ConfigureAwait(false); + var pipe = new Pipe(); + var fillPipeTask = handler.FillPipeAsync(attachment, pipe.Writer); + result = await LogParser.ReadPipeAsync(pipe.Reader).ConfigureAwait(false); + await fillPipeTask.ConfigureAwait(false); } catch (Exception e) { - args.Client.DebugLogger.LogMessage(LogLevel.Error, "", "Sending log results failed: " + e, DateTime.Now); + args.Client.DebugLogger.LogMessage(LogLevel.Error, "", "Log parsing failed: " + e, DateTime.Now); } + if (result == null) + await args.Channel.SendMessageAsync("Log analysis failed, most likely cause is a truncated/invalid log. Please run the game again and reupload the new copy.") + .ConfigureAwait(false); + else + { + try + { + if (result.Error == LogParseState.ErrorCode.PiracyDetected) + { + if (args.Author.IsWhitelisted(args.Client, args.Guild)) + { + await Task.WhenAll( + args.Channel.SendMessageAsync("I see wha' ye did thar ☠"), + args.Client.ReportAsync("Pirated Release (whitelisted by role)", args.Message, result.PiracyTrigger, result.PiracyContext, ReportSeverity.Low) + ).ConfigureAwait(false); + } + else + { + var severity = ReportSeverity.Low; + try + { + await message.DeleteAsync("Piracy detected in log").ConfigureAwait(false); + } + catch (Exception e) + { + severity = ReportSeverity.High; + args.Client.DebugLogger.LogMessage(LogLevel.Warning, "", $"Unable to delete message in {args.Channel.Name}: {e.Message}", DateTime.Now); + } + await args.Channel.SendMessageAsync(embed: await result.AsEmbedAsync(args.Client, args.Message).ConfigureAwait(false)).ConfigureAwait(false); + await Task.WhenAll( + args.Client.ReportAsync("Pirated Release", args.Message, result.PiracyTrigger, result.PiracyContext, severity), + Warnings.AddAsync(args.Client, args.Message, args.Message.Author.Id, args.Message.Author.Username, args.Client.CurrentUser, + "Pirated Release", $"{message.Content.Sanitize()} - {result.PiracyTrigger}") + ); + } + } + else + await args.Channel.SendMessageAsync(embed: await result.AsEmbedAsync(args.Client, args.Message).ConfigureAwait(false)).ConfigureAwait(false); + } + catch (Exception e) + { + args.Client.DebugLogger.LogMessage(LogLevel.Error, "", "Sending log results failed: " + e, DateTime.Now); + } + } + return; } + + if (string.IsNullOrEmpty(message.Content) || !"help".Equals(args.Channel.Name, StringComparison.InvariantCultureIgnoreCase)) return; + + var linkStart = message.Content.IndexOf("http"); + if (linkStart > -1) + { + var link = message.Content.Substring(linkStart).Split(linkSeparator, 2)[0]; + if (link.Contains(".log", StringComparison.InvariantCultureIgnoreCase) || link.Contains("rpcs3.zip", StringComparison.CurrentCultureIgnoreCase)) + await args.Channel.SendMessageAsync("If you intended to upload a log file please re-upload it directly to discord").ConfigureAwait(false); } - - if (string.IsNullOrEmpty(message.Content) || !"help".Equals(args.Channel.Name, StringComparison.InvariantCultureIgnoreCase)) - return; - - var linkStart = message.Content.IndexOf("http"); - if (linkStart > -1) + } + finally { - var link = message.Content.Substring(linkStart).Split(linkSeparator, 2)[0]; - if (link.Contains(".log", StringComparison.InvariantCultureIgnoreCase) || link.Contains("rpcs3.zip", StringComparison.CurrentCultureIgnoreCase)) - await args.Channel.SendMessageAsync("If you intended to upload a log file please reupload it directly to discord").ConfigureAwait(false); + QueueLimiter.Release(); + if (parsedLog) + Console.WriteLine($"<<<<<<< {message.Id % 100} Finished parsing in {startTime.Elapsed}"); } } - finally + catch (Exception e) { - QueueLimiter.Release(); - if (parsedLog) - Console.WriteLine($"<<<<<<< {message.Id % 100} Finished parsing in {startTime.Elapsed}"); + args.Client.DebugLogger.LogMessage(LogLevel.Error, "", e.ToString(), DateTime.Now); } } } diff --git a/CompatBot/ThumbScrapper/PsnScraper.cs b/CompatBot/ThumbScrapper/PsnScraper.cs index 2da9fa37..8975789f 100644 --- a/CompatBot/ThumbScrapper/PsnScraper.cs +++ b/CompatBot/ThumbScrapper/PsnScraper.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using CompatBot.Database; using CompatBot.Database.Providers; using CompatBot.EventHandlers; +using DSharpPlus; using DSharpPlus.CommandsNext; using PsnClient.POCOs; using PsnClient.Utils; @@ -82,6 +83,10 @@ namespace CompatBot.ThumbScrapper } await ctx.RespondAsync($"Didn't find {contentId} in any PSN store").ConfigureAwait(false); } + catch (Exception e) + { + ctx.Client.DebugLogger.LogMessage(LogLevel.Error, "", e.ToString(), DateTime.Now); + } finally { QueueLimiter.Release(); diff --git a/CompatBot/Utils/AutosplitResponseHelper.cs b/CompatBot/Utils/AutosplitResponseHelper.cs index 4e95995e..f6991ae3 100644 --- a/CompatBot/Utils/AutosplitResponseHelper.cs +++ b/CompatBot/Utils/AutosplitResponseHelper.cs @@ -45,7 +45,8 @@ namespace CompatBot.Utils { if (buffer.Length + line.Length + blockEnd.Length > blockSize) { - await channel.SendMessageAsync(buffer.Append(blockEnd).ToString()).ConfigureAwait(false); + var content = buffer.ToString().Trim(blockSize - blockEnd.Length) + blockEnd; + await channel.SendMessageAsync(content).ConfigureAwait(false); await channel.TriggerTypingAsync().ConfigureAwait(false); buffer.Clear().Append(blockStart); }