From 8732850718a90b79768601d5443684ff0661b63b Mon Sep 17 00:00:00 2001 From: Bagus Nur Listiyono Date: Fri, 8 Nov 2024 22:00:29 +0700 Subject: [PATCH 01/33] Initial implementation for Sentry SDK The server running is using a local dinky server, pls no abooze. TODO: Implement Sentry catcher to ALL EXCEPTION HOLY THAT IS A LOT --- CollapseLauncher/App.xaml.cs | 14 ++++++++++-- CollapseLauncher/CollapseLauncher.csproj | 1 + CollapseLauncher/Program.cs | 29 ++++++++++++++++++++++++ CollapseLauncher/packages.lock.json | 6 +++++ 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/CollapseLauncher/App.xaml.cs b/CollapseLauncher/App.xaml.cs index 28a54554d..7c6f33ff4 100644 --- a/CollapseLauncher/App.xaml.cs +++ b/CollapseLauncher/App.xaml.cs @@ -10,6 +10,8 @@ using System; using System.Linq; using Windows.UI; +using Sentry; +using Sentry.Protocol; using static CollapseLauncher.InnerLauncherConfig; using static Hi3Helper.InvokeProp; using static Hi3Helper.Logger; @@ -51,9 +53,17 @@ public App() UnhandledException += static (sender, e) => { LogWriteLine($"[XAML_OTHER] Sender: {sender}\r\n{e!.Exception} {e.Exception!.InnerException}", LogType.Error, true); - #if !DEBUG + var ex = e.Exception; + if (ex != null) + { + ex.Data[Mechanism.HandledKey] = false; + ex.Data[Mechanism.MechanismKey] = "Application.XamlUnhandledException"; + SentrySdk.CaptureException(ex); + SentrySdk.FlushAsync(TimeSpan.FromSeconds(1)).GetAwaiter().GetResult(); + } +#if !DEBUG MainEntryPoint.SpawnFatalErrorConsole(e!.Exception); - #endif +#endif }; } diff --git a/CollapseLauncher/CollapseLauncher.csproj b/CollapseLauncher/CollapseLauncher.csproj index 13011aa2e..66b96bdcd 100644 --- a/CollapseLauncher/CollapseLauncher.csproj +++ b/CollapseLauncher/CollapseLauncher.csproj @@ -140,6 +140,7 @@ --> + diff --git a/CollapseLauncher/Program.cs b/CollapseLauncher/Program.cs index 81d59e56a..4e8887cb6 100644 --- a/CollapseLauncher/Program.cs +++ b/CollapseLauncher/Program.cs @@ -22,6 +22,8 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using Sentry; +using Sentry.Infrastructure; using WinRT; using static CollapseLauncher.ArgumentParser; using static CollapseLauncher.InnerLauncherConfig; @@ -78,6 +80,33 @@ public static void Main(params string[] args) LogType.Warning, true); Directory.SetCurrentDirectory(AppFolder); } + + // Sentry SDK Entry + // TODO: Make this disableable or whatever that spelled + SentrySdk.Init(o => + { + o.Dsn = "https://2acc39f86f2b4f5a99bac09494af13c6@bugsink.bagelnl.my.id/1"; + +#if DEBUG + o.Debug = true; + o.DiagnosticLogger = new ConsoleDiagnosticLogger(SentryLevel.Debug); + o.DiagnosticLevel = SentryLevel.Debug; +#else + o.Debug = false; +#endif + o.TracesSampleRate = 1.0; + o.IsGlobalModeEnabled = true; + o.DisableWinUiUnhandledExceptionIntegration(); + o.StackTraceMode = StackTraceMode.Enhanced; + +#if DEBUG + o.Distribution = "Debug"; +#else + o.Distribution = IsPreview ? "Preview" : "Stable"; +#endif + + o.MaxAttachmentSize = 5 * 1024 * 1024; // 5 MB + }); StartUpdaterHook(); diff --git a/CollapseLauncher/packages.lock.json b/CollapseLauncher/packages.lock.json index c15e1f472..9c4045c51 100644 --- a/CollapseLauncher/packages.lock.json +++ b/CollapseLauncher/packages.lock.json @@ -196,6 +196,12 @@ "resolved": "9.0.0-rc.2.24473.5", "contentHash": "gtZORh0O2hlNn8D+ezseJs1SEAI83Ca+LC8vmAIqaYUbiAn5+6iqD+ytuztGo4Thjr/2qWXKn3l7GGQEQiCJMg==" }, + "Sentry": { + "type": "Direct", + "requested": "[4.13.0, )", + "resolved": "4.13.0", + "contentHash": "Wfw3M1WpFcrYaGzPm7QyUTfIOYkVXQ1ry6p4WYjhbLz9fPwV23SGQZTFDpdox67NHM0V0g1aoQ4YKLm4ANtEEg==" + }, "SharpCompress": { "type": "Direct", "requested": "[0.38.0, )", From d0a32116331d2a38d8f6571ca14481b05cb92c62 Mon Sep 17 00:00:00 2001 From: Ron Friedman Date: Fri, 8 Nov 2024 14:14:51 -0500 Subject: [PATCH 02/33] add new global constant `USEREMOTELOGGING`, automatically enabled on Preview & Debug branches for obvious reasons. update logger types --- CollapseLauncher/CollapseLauncher.csproj | 7 ++++--- CollapseLauncher/Program.cs | 4 +++- Hi3Helper.Core/Classes/Logger/Enum/LogType.cs | 3 ++- Hi3Helper.Core/Classes/Logger/LoggerBase.cs | 4 +++- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/CollapseLauncher/CollapseLauncher.csproj b/CollapseLauncher/CollapseLauncher.csproj index 66b96bdcd..de387d163 100644 --- a/CollapseLauncher/CollapseLauncher.csproj +++ b/CollapseLauncher/CollapseLauncher.csproj @@ -1,4 +1,4 @@ - + WinExe @@ -71,11 +71,12 @@ This decoder supports lots of newest format, including AV1, HEVC and MPEG-DASH Contained video. - USENEWZIPDECOMPRESS : Use sharpcompress for decompressing .zip game package files - USEVELOPACK : Use Velopack as the update manager + - USEREMOTELOGGING : Use Sentry SDK to log errors remotely to Bugsink instance --> - DISABLE_XAML_GENERATED_MAIN;USEVELOPACK;USENEWZIPDECOMPRESS;ENABLEHTTPREPAIR;DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION;PREVIEW;DUMPGIJSON;SIMULATEGIHDR;GSPBYPASSGAMERUNNING;MHYPLUGINSUPPORT + DISABLE_XAML_GENERATED_MAIN;USEVELOPACK;USENEWZIPDECOMPRESS;ENABLEHTTPREPAIR;DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION;PREVIEW;DUMPGIJSON;SIMULATEGIHDR;GSPBYPASSGAMERUNNING;MHYPLUGINSUPPORT;USEREMOTELOGGING full @@ -88,7 +89,7 @@ - DISABLE_XAML_GENERATED_MAIN;USEVELOPACK;USENEWZIPDECOMPRESS;ENABLEHTTPREPAIR;DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION;MHYPLUGINSUPPORT + DISABLE_XAML_GENERATED_MAIN;USEVELOPACK;USENEWZIPDECOMPRESS;ENABLEHTTPREPAIR;DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION;MHYPLUGINSUPPORT;USEREMOTELOGGING true true diff --git a/CollapseLauncher/Program.cs b/CollapseLauncher/Program.cs index 4e8887cb6..7591f207f 100644 --- a/CollapseLauncher/Program.cs +++ b/CollapseLauncher/Program.cs @@ -82,7 +82,8 @@ public static void Main(params string[] args) } // Sentry SDK Entry - // TODO: Make this disableable or whatever that spelled +#if USEREMOTELOGGING + LogWriteLine("Initializing SentrySdk...", LogType.Remote, false); SentrySdk.Init(o => { o.Dsn = "https://2acc39f86f2b4f5a99bac09494af13c6@bugsink.bagelnl.my.id/1"; @@ -107,6 +108,7 @@ public static void Main(params string[] args) o.MaxAttachmentSize = 5 * 1024 * 1024; // 5 MB }); +#endif StartUpdaterHook(); diff --git a/Hi3Helper.Core/Classes/Logger/Enum/LogType.cs b/Hi3Helper.Core/Classes/Logger/Enum/LogType.cs index d9062a622..e0fdd2617 100644 --- a/Hi3Helper.Core/Classes/Logger/Enum/LogType.cs +++ b/Hi3Helper.Core/Classes/Logger/Enum/LogType.cs @@ -9,6 +9,7 @@ public enum LogType NoTag, Game, Debug, - GLC + GLC, + Remote } } diff --git a/Hi3Helper.Core/Classes/Logger/LoggerBase.cs b/Hi3Helper.Core/Classes/Logger/LoggerBase.cs index 03c04a290..63ad046d7 100644 --- a/Hi3Helper.Core/Classes/Logger/LoggerBase.cs +++ b/Hi3Helper.Core/Classes/Logger/LoggerBase.cs @@ -240,7 +240,7 @@ private void InitializeWriter(bool isFallback, Encoding logEncoding) private int GetTotalInstance() => InvokeProp.EnumerateInstances(); #endif - private ArgumentException ThrowInvalidType() => new ArgumentException("Type must be Default, Error, Warning, Scheme, Game, NoTag or Empty!"); + private ArgumentException ThrowInvalidType() => new ArgumentException("Type must be Default, Error, Warning, Scheme, Game, Debug, GLC, Remote or Empty!"); /// /// Get the ASCII color in string form. @@ -256,6 +256,7 @@ private void InitializeWriter(bool isFallback, Encoding logEncoding) LogType.Game => "\u001b[35;1m", LogType.Debug => "\u001b[36;1m", LogType.GLC => "\u001b[91;1m", + LogType.Remote => "\u001b[42;1m", _ => string.Empty }; @@ -274,6 +275,7 @@ private void InitializeWriter(bool isFallback, Encoding logEncoding) LogType.Game => "[Game] ", LogType.Debug => "[DBG] ", LogType.GLC => "[GLC] ", + LogType.Remote => "[Remo] ", LogType.NoTag => " ", _ => throw ThrowInvalidType() }; From a1de6fc6b3f8793d288db63cefc18d57d67023aa Mon Sep 17 00:00:00 2001 From: Ron Friedman Date: Fri, 8 Nov 2024 14:15:32 -0500 Subject: [PATCH 03/33] add toggle in settings for sentrysdk usage Does not initialize or de-initialize the utility. Note: An app restart may be required when selecting the option --- CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml | 7 +++++++ .../XAMLs/MainApp/Pages/SettingsPage.xaml.cs | 10 ++++++++++ Hi3Helper.Core/Classes/Shared/Region/LauncherConfig.cs | 4 ++++ Hi3Helper.Core/Lang/Locale/LangSettingsPage.cs | 1 + Hi3Helper.Core/Lang/en_US.json | 1 + 5 files changed, 23 insertions(+) diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml b/CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml index c6539bf6d..e38138df7 100644 --- a/CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml +++ b/CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml @@ -1335,6 +1335,13 @@ OffContent="{x:Bind helper:Locale.Lang._Misc.Disabled}" OnContent="{x:Bind helper:Locale.Lang._Misc.Enabled}" Visibility="Collapsed" /> + GetAppConfigValue("SendRemoteCrashData").ToBool(); + set + { + SetAndSaveConfigValue("SendRemoteCrashData", value); + // TODO: Include some setup stuff here + } + } + private bool IsIntroEnabled { get => LauncherConfig.IsIntroEnabled; diff --git a/Hi3Helper.Core/Classes/Shared/Region/LauncherConfig.cs b/Hi3Helper.Core/Classes/Shared/Region/LauncherConfig.cs index 07ed5c447..f696e7f46 100644 --- a/Hi3Helper.Core/Classes/Shared/Region/LauncherConfig.cs +++ b/Hi3Helper.Core/Classes/Shared/Region/LauncherConfig.cs @@ -408,6 +408,10 @@ public static Guid GetGuid(int sessionNum) #else { "EnableConsole", false }, #endif + #if USEREMOTELOGGING + { "SendRemoteCrashData", true }, + #endif + { "SendRemoteCrashData", false }, { "EnableMultipleInstance", false }, { "DontAskUpdate", false }, { "ThemeMode", new IniValue(AppThemeMode.Default) }, diff --git a/Hi3Helper.Core/Lang/Locale/LangSettingsPage.cs b/Hi3Helper.Core/Lang/Locale/LangSettingsPage.cs index b8b89695e..8b84e181a 100644 --- a/Hi3Helper.Core/Lang/Locale/LangSettingsPage.cs +++ b/Hi3Helper.Core/Lang/Locale/LangSettingsPage.cs @@ -16,6 +16,7 @@ public sealed partial class LangSettingsPage public string Debug { get; set; } = LangFallback?._SettingsPage.Debug; public string Debug_Console { get; set; } = LangFallback?._SettingsPage.Debug_Console; public string Debug_IncludeGameLogs { get; set; } = LangFallback?._SettingsPage.Debug_IncludeGameLogs; + public string Debug_SendRemoteCrashData { get; set; } = LangFallback?._SettingsPage.Debug_SendRemoteCrashData; public string Debug_MultipleInstance { get; set; } = LangFallback?._SettingsPage.Debug_MultipleInstance; public string ChangeRegionWarning_Toggle { get; set; } = LangFallback?._SettingsPage.ChangeRegionWarning_Toggle; public string ChangeRegionInstant_Toggle { get; set; } = LangFallback?._SettingsPage.ChangeRegionInstant_Toggle; diff --git a/Hi3Helper.Core/Lang/en_US.json b/Hi3Helper.Core/Lang/en_US.json index 2b5f03e90..b8fa046dd 100644 --- a/Hi3Helper.Core/Lang/en_US.json +++ b/Hi3Helper.Core/Lang/en_US.json @@ -422,6 +422,7 @@ "Debug": "Additional Settings", "Debug_Console": "Show Console", "Debug_IncludeGameLogs": "Save Game logs to Collapse's (might contain sensitive data)", + "Debug_SendRemoteCrashData": "Send anonymous crash reports to developers", "Debug_MultipleInstance": "Allow running multiple instances of Collapse", "ChangeRegionWarning_Toggle": "Show Region Change Warning", From 2e72ff9a8898a9c3a0536bcc44f85c0a8037ca36 Mon Sep 17 00:00:00 2001 From: Ron Friedman Date: Fri, 8 Nov 2024 16:23:58 -0500 Subject: [PATCH 04/33] install sentry in helper --- CollapseLauncher/packages.lock.json | 3 ++- Hi3Helper.Core/Hi3Helper.Core.csproj | 1 + Hi3Helper.Core/packages.lock.json | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CollapseLauncher/packages.lock.json b/CollapseLauncher/packages.lock.json index 9c4045c51..491573309 100644 --- a/CollapseLauncher/packages.lock.json +++ b/CollapseLauncher/packages.lock.json @@ -407,7 +407,8 @@ "type": "Project", "dependencies": { "Hi3Helper.EncTool": "[1.0.0, )", - "Microsoft.Windows.CsWinRT": "[2.1.6, )" + "Microsoft.Windows.CsWinRT": "[2.1.6, )", + "Sentry": "[4.13.0, )" } }, "hi3helper.enctool": { diff --git a/Hi3Helper.Core/Hi3Helper.Core.csproj b/Hi3Helper.Core/Hi3Helper.Core.csproj index 3ab15cec3..87d2c0a42 100644 --- a/Hi3Helper.Core/Hi3Helper.Core.csproj +++ b/Hi3Helper.Core/Hi3Helper.Core.csproj @@ -43,6 +43,7 @@ + diff --git a/Hi3Helper.Core/packages.lock.json b/Hi3Helper.Core/packages.lock.json index 4167108f2..20856c3ee 100644 --- a/Hi3Helper.Core/packages.lock.json +++ b/Hi3Helper.Core/packages.lock.json @@ -14,6 +14,12 @@ "resolved": "2.1.6", "contentHash": "k5G30dezZjGnGyLokTkj+yBX9gyAhDSm8pY7MqEUX1Dorl4GfSywfodOA8wmhFaNuUd4OI6q1MuQQaxQIA/t0w==" }, + "Sentry": { + "type": "Direct", + "requested": "[4.13.0, )", + "resolved": "4.13.0", + "contentHash": "Wfw3M1WpFcrYaGzPm7QyUTfIOYkVXQ1ry6p4WYjhbLz9fPwV23SGQZTFDpdox67NHM0V0g1aoQ4YKLm4ANtEEg==" + }, "Google.Protobuf": { "type": "Transitive", "resolved": "3.28.3", From aa24ff11a331080f631c673ff1a3d47082707671 Mon Sep 17 00:00:00 2001 From: Ron Friedman Date: Fri, 8 Nov 2024 16:24:51 -0500 Subject: [PATCH 05/33] wrap exception calls in global exception handler sends it to Sentry so we don't have to refactor all our exception calls --- .../Remote/Classes/GlobalSentryHandler.cs | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 Hi3Helper.Core/Classes/Remote/Classes/GlobalSentryHandler.cs diff --git a/Hi3Helper.Core/Classes/Remote/Classes/GlobalSentryHandler.cs b/Hi3Helper.Core/Classes/Remote/Classes/GlobalSentryHandler.cs new file mode 100644 index 000000000..0bcbddda3 --- /dev/null +++ b/Hi3Helper.Core/Classes/Remote/Classes/GlobalSentryHandler.cs @@ -0,0 +1,55 @@ +using Sentry; +using Sentry.Infrastructure; +using System; +using System.Threading.Tasks; + +namespace Hi3Helper.Core.Classes.Remote +{ + public class GlobalSentryHandler + { + public static void InitializeExceptionRedirector() + { + // Handle any unhandled errors in app domain + // https://learn.microsoft.com/en-us/dotnet/api/system.appdomain?view=net-9.0 + AppDomain.CurrentDomain.UnhandledException += (sender, args) => + { + var ex = args.ExceptionObject as Exception; + SentrySdk.CaptureException(ex); + }; + + TaskScheduler.UnobservedTaskException += (sender, args) => + { + SentrySdk.CaptureException(args.Exception); + args.SetObserved(); + }; + } + + public static void InitializeSentrySdk() + { + SentrySdk.Init(o => + { + o.Dsn = "https://2acc39f86f2b4f5a99bac09494af13c6@bugsink.bagelnl.my.id/1"; + +#if DEBUG + o.Debug = true; + o.DiagnosticLogger = new ConsoleDiagnosticLogger(SentryLevel.Debug); + o.DiagnosticLevel = SentryLevel.Debug; +#else + o.Debug = false; +#endif + o.TracesSampleRate = 1.0; + o.IsGlobalModeEnabled = true; + o.DisableWinUiUnhandledExceptionIntegration(); + o.StackTraceMode = StackTraceMode.Enhanced; + +#if DEBUG + o.Distribution = "Debug"; +#else + o.Distribution = IsPreview ? "Preview" : "Stable"; +#endif + + o.MaxAttachmentSize = 5 * 1024 * 1024; // 5 MB + }); + } + } +} \ No newline at end of file From ca948138adf763d32d123979993ee169cf28594e Mon Sep 17 00:00:00 2001 From: Ron Friedman Date: Fri, 8 Nov 2024 16:27:12 -0500 Subject: [PATCH 06/33] remove unecessary init calls in main func Move SentrySDK init to its own helper --- CollapseLauncher/Program.cs | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/CollapseLauncher/Program.cs b/CollapseLauncher/Program.cs index 7591f207f..af0828889 100644 --- a/CollapseLauncher/Program.cs +++ b/CollapseLauncher/Program.cs @@ -1,6 +1,7 @@ using CollapseLauncher.Helper; using CollapseLauncher.Helper.Update; using Hi3Helper; +using Hi3Helper.Core.Classes.Remote; using Hi3Helper.Http.Legacy; using Hi3Helper.Shared.ClassStruct; using InnoSetupHelper; @@ -82,33 +83,20 @@ public static void Main(params string[] args) } // Sentry SDK Entry -#if USEREMOTELOGGING - LogWriteLine("Initializing SentrySdk...", LogType.Remote, false); - SentrySdk.Init(o => + LogWriteLine("Setting up global exception handler redirection", LogType.Scheme, true); + GlobalSentryHandler.InitializeSentrySdk(); + LogWriteLine("Loading Sentry SDK...", LogType.Remote, true); + try { - o.Dsn = "https://2acc39f86f2b4f5a99bac09494af13c6@bugsink.bagelnl.my.id/1"; - -#if DEBUG - o.Debug = true; - o.DiagnosticLogger = new ConsoleDiagnosticLogger(SentryLevel.Debug); - o.DiagnosticLevel = SentryLevel.Debug; -#else - o.Debug = false; -#endif - o.TracesSampleRate = 1.0; - o.IsGlobalModeEnabled = true; - o.DisableWinUiUnhandledExceptionIntegration(); - o.StackTraceMode = StackTraceMode.Enhanced; - + GlobalSentryHandler.InitializeExceptionRedirector(); + } + catch (Exception ex) + { + LogWriteLine("Failed to load Sentry SDK.", LogType.Remote, true); #if DEBUG - o.Distribution = "Debug"; -#else - o.Distribution = IsPreview ? "Preview" : "Stable"; -#endif - - o.MaxAttachmentSize = 5 * 1024 * 1024; // 5 MB - }); + LogWriteLine(ex.Message, LogType.Debug, true); #endif + } StartUpdaterHook(); From ea45a30d6402ce04b27d8d1dad2e4168b7f324f1 Mon Sep 17 00:00:00 2001 From: Bagus Nur Listiyono Date: Sat, 9 Nov 2024 17:56:49 +0700 Subject: [PATCH 07/33] Refactor --- CollapseLauncher/App.xaml.cs | 6 +- CollapseLauncher/CollapseLauncher.csproj | 5 +- CollapseLauncher/Program.cs | 30 ++-- Hi3Helper.Core/Classes/Logger/Enum/LogType.cs | 2 +- Hi3Helper.Core/Classes/Logger/LoggerBase.cs | 4 +- .../Remote/Classes/GlobalSentryHandler.cs | 55 ------- .../Classes/SentryHelper/SentryHelper.cs | 149 ++++++++++++++++++ .../Classes/Shared/Region/LauncherConfig.cs | 3 - 8 files changed, 173 insertions(+), 81 deletions(-) delete mode 100644 Hi3Helper.Core/Classes/Remote/Classes/GlobalSentryHandler.cs create mode 100644 Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs diff --git a/CollapseLauncher/App.xaml.cs b/CollapseLauncher/App.xaml.cs index 7c6f33ff4..880a72bf6 100644 --- a/CollapseLauncher/App.xaml.cs +++ b/CollapseLauncher/App.xaml.cs @@ -10,6 +10,7 @@ using System; using System.Linq; using Windows.UI; +using Hi3Helper.Core.SentryHelper; using Sentry; using Sentry.Protocol; using static CollapseLauncher.InnerLauncherConfig; @@ -56,10 +57,7 @@ public App() var ex = e.Exception; if (ex != null) { - ex.Data[Mechanism.HandledKey] = false; - ex.Data[Mechanism.MechanismKey] = "Application.XamlUnhandledException"; - SentrySdk.CaptureException(ex); - SentrySdk.FlushAsync(TimeSpan.FromSeconds(1)).GetAwaiter().GetResult(); + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledXaml); } #if !DEBUG MainEntryPoint.SpawnFatalErrorConsole(e!.Exception); diff --git a/CollapseLauncher/CollapseLauncher.csproj b/CollapseLauncher/CollapseLauncher.csproj index de387d163..7652f1ab3 100644 --- a/CollapseLauncher/CollapseLauncher.csproj +++ b/CollapseLauncher/CollapseLauncher.csproj @@ -71,12 +71,11 @@ This decoder supports lots of newest format, including AV1, HEVC and MPEG-DASH Contained video. - USENEWZIPDECOMPRESS : Use sharpcompress for decompressing .zip game package files - USEVELOPACK : Use Velopack as the update manager - - USEREMOTELOGGING : Use Sentry SDK to log errors remotely to Bugsink instance --> - DISABLE_XAML_GENERATED_MAIN;USEVELOPACK;USENEWZIPDECOMPRESS;ENABLEHTTPREPAIR;DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION;PREVIEW;DUMPGIJSON;SIMULATEGIHDR;GSPBYPASSGAMERUNNING;MHYPLUGINSUPPORT;USEREMOTELOGGING + DISABLE_XAML_GENERATED_MAIN;USEVELOPACK;USENEWZIPDECOMPRESS;ENABLEHTTPREPAIR;DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION;PREVIEW;DUMPGIJSON;SIMULATEGIHDR;GSPBYPASSGAMERUNNING;MHYPLUGINSUPPORT full @@ -89,7 +88,7 @@ - DISABLE_XAML_GENERATED_MAIN;USEVELOPACK;USENEWZIPDECOMPRESS;ENABLEHTTPREPAIR;DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION;MHYPLUGINSUPPORT;USEREMOTELOGGING + DISABLE_XAML_GENERATED_MAIN;USEVELOPACK;USENEWZIPDECOMPRESS;ENABLEHTTPREPAIR;DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION;MHYPLUGINSUPPORT true true diff --git a/CollapseLauncher/Program.cs b/CollapseLauncher/Program.cs index af0828889..531e429cc 100644 --- a/CollapseLauncher/Program.cs +++ b/CollapseLauncher/Program.cs @@ -1,7 +1,7 @@ using CollapseLauncher.Helper; using CollapseLauncher.Helper.Update; using Hi3Helper; -using Hi3Helper.Core.Classes.Remote; +using Hi3Helper.Core.SentryHelper; using Hi3Helper.Http.Legacy; using Hi3Helper.Shared.ClassStruct; using InnoSetupHelper; @@ -81,21 +81,25 @@ public static void Main(params string[] args) LogType.Warning, true); Directory.SetCurrentDirectory(AppFolder); } - - // Sentry SDK Entry - LogWriteLine("Setting up global exception handler redirection", LogType.Scheme, true); - GlobalSentryHandler.InitializeSentrySdk(); - LogWriteLine("Loading Sentry SDK...", LogType.Remote, true); - try - { - GlobalSentryHandler.InitializeExceptionRedirector(); - } - catch (Exception ex) + + + if (SentryHelper.IsEnabled) { - LogWriteLine("Failed to load Sentry SDK.", LogType.Remote, true); + try + { + // Sentry SDK Entry + LogWriteLine("Setting up global exception handler redirection", LogType.Scheme, true); + LogWriteLine("Loading Sentry SDK...", LogType.Sentry, true); + SentryHelper.InitializeSentrySdk(); + SentryHelper.InitializeExceptionRedirect(); + } + catch (Exception ex) + { + LogWriteLine("Failed to load Sentry SDK.", LogType.Sentry, true); #if DEBUG - LogWriteLine(ex.Message, LogType.Debug, true); + LogWriteLine(ex.Message, LogType.Debug, true); #endif + } } StartUpdaterHook(); diff --git a/Hi3Helper.Core/Classes/Logger/Enum/LogType.cs b/Hi3Helper.Core/Classes/Logger/Enum/LogType.cs index e0fdd2617..83383d2e7 100644 --- a/Hi3Helper.Core/Classes/Logger/Enum/LogType.cs +++ b/Hi3Helper.Core/Classes/Logger/Enum/LogType.cs @@ -10,6 +10,6 @@ public enum LogType Game, Debug, GLC, - Remote + Sentry } } diff --git a/Hi3Helper.Core/Classes/Logger/LoggerBase.cs b/Hi3Helper.Core/Classes/Logger/LoggerBase.cs index 63ad046d7..8dd55298a 100644 --- a/Hi3Helper.Core/Classes/Logger/LoggerBase.cs +++ b/Hi3Helper.Core/Classes/Logger/LoggerBase.cs @@ -256,7 +256,7 @@ private void InitializeWriter(bool isFallback, Encoding logEncoding) LogType.Game => "\u001b[35;1m", LogType.Debug => "\u001b[36;1m", LogType.GLC => "\u001b[91;1m", - LogType.Remote => "\u001b[42;1m", + LogType.Sentry => "\u001b[42;1m", _ => string.Empty }; @@ -275,7 +275,7 @@ private void InitializeWriter(bool isFallback, Encoding logEncoding) LogType.Game => "[Game] ", LogType.Debug => "[DBG] ", LogType.GLC => "[GLC] ", - LogType.Remote => "[Remo] ", + LogType.Sentry => "[Remo] ", LogType.NoTag => " ", _ => throw ThrowInvalidType() }; diff --git a/Hi3Helper.Core/Classes/Remote/Classes/GlobalSentryHandler.cs b/Hi3Helper.Core/Classes/Remote/Classes/GlobalSentryHandler.cs deleted file mode 100644 index 0bcbddda3..000000000 --- a/Hi3Helper.Core/Classes/Remote/Classes/GlobalSentryHandler.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Sentry; -using Sentry.Infrastructure; -using System; -using System.Threading.Tasks; - -namespace Hi3Helper.Core.Classes.Remote -{ - public class GlobalSentryHandler - { - public static void InitializeExceptionRedirector() - { - // Handle any unhandled errors in app domain - // https://learn.microsoft.com/en-us/dotnet/api/system.appdomain?view=net-9.0 - AppDomain.CurrentDomain.UnhandledException += (sender, args) => - { - var ex = args.ExceptionObject as Exception; - SentrySdk.CaptureException(ex); - }; - - TaskScheduler.UnobservedTaskException += (sender, args) => - { - SentrySdk.CaptureException(args.Exception); - args.SetObserved(); - }; - } - - public static void InitializeSentrySdk() - { - SentrySdk.Init(o => - { - o.Dsn = "https://2acc39f86f2b4f5a99bac09494af13c6@bugsink.bagelnl.my.id/1"; - -#if DEBUG - o.Debug = true; - o.DiagnosticLogger = new ConsoleDiagnosticLogger(SentryLevel.Debug); - o.DiagnosticLevel = SentryLevel.Debug; -#else - o.Debug = false; -#endif - o.TracesSampleRate = 1.0; - o.IsGlobalModeEnabled = true; - o.DisableWinUiUnhandledExceptionIntegration(); - o.StackTraceMode = StackTraceMode.Enhanced; - -#if DEBUG - o.Distribution = "Debug"; -#else - o.Distribution = IsPreview ? "Preview" : "Stable"; -#endif - - o.MaxAttachmentSize = 5 * 1024 * 1024; // 5 MB - }); - } - } -} \ No newline at end of file diff --git a/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs b/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs new file mode 100644 index 000000000..4943e76bb --- /dev/null +++ b/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs @@ -0,0 +1,149 @@ +using Sentry; +using Sentry.Infrastructure; +using System; +using System.Threading.Tasks; +using Hi3Helper.Shared.Region; +using Sentry.Protocol; + +#nullable enable +namespace Hi3Helper.Core.SentryHelper +{ + public static class SentryHelper + { + public enum ExceptionType + { + UnhandledXaml, + UnhandledOther, + Handled + } + + private static bool? _isEnabled; + public static bool IsEnabled + { + get => _isEnabled ??= LauncherConfig.GetAppConfigValue("SendRemoteCrashData").ToBool(); + set + { + if (value == _isEnabled) return; + + if (value) + { + InitializeSentrySdk(); + } + else + { + StopSentrySdk(); + } + + _isEnabled = value; + LauncherConfig.SetAndSaveConfigValue("SendRemoteCrashData", value); + } + } + + + public static void InitializeSentrySdk() + { + SentrySdk.Init(o => + { + o.Dsn = "https://2acc39f86f2b4f5a99bac09494af13c6@bugsink.bagelnl.my.id/1"; + +#if DEBUG + o.Debug = true; + o.DiagnosticLogger = new ConsoleDiagnosticLogger(SentryLevel.Debug); + o.DiagnosticLevel = SentryLevel.Debug; +#else + o.Debug = false; +#endif + o.TracesSampleRate = 1.0; + o.IsGlobalModeEnabled = true; + o.DisableWinUiUnhandledExceptionIntegration(); // Use this for trimmed/NativeAOT published app + o.StackTraceMode = StackTraceMode.Enhanced; + +#if DEBUG + o.Distribution = "Debug"; +#else + o.Distribution = IsPreview ? "Preview" : "Stable"; +#endif + + o.MaxAttachmentSize = 5 * 1024 * 1024; // 5 MB + }); + } + + private static void StopSentrySdk() => SentrySdk.EndSession(); + + public static void InitializeExceptionRedirect() + { + // Handle any unhandled errors in app domain + // https://learn.microsoft.com/en-us/dotnet/api/system.appdomain?view=net-9.0 + AppDomain.CurrentDomain.UnhandledException += (_, args) => + { + var ex = args.ExceptionObject as Exception; + if (ex == null) return; + ex.Data[Mechanism.HandledKey] = false; + ex.Data[Mechanism.MechanismKey] = "Application.UnhandledException"; + SentrySdk.CaptureException(ex); + SentrySdk.FlushAsync(TimeSpan.FromSeconds(1)).GetAwaiter().GetResult(); + }; + + TaskScheduler.UnobservedTaskException += (_, args) => + { + SentrySdk.CaptureException(args.Exception); + SentrySdk.FlushAsync(TimeSpan.FromSeconds(1)).GetAwaiter().GetResult(); + args.SetObserved(); + }; + } + + /// + /// Sends exception to Sentry's set DSN + /// + /// + /// + public static void ExceptionHandler(Exception ex, ExceptionType exT = ExceptionType.UnhandledOther) + { + if (!IsEnabled) return; + ex.Data[Mechanism.HandledKey] = exT == ExceptionType.Handled; + if (exT == ExceptionType.UnhandledXaml) + ex.Data[Mechanism.MechanismKey] = "Application.XamlUnhandledException"; + SentrySdk.CaptureException(ex); + SentrySdk.FlushAsync(TimeSpan.FromSeconds(1)).GetAwaiter().GetResult(); + } + + public static async Task ExceptionHandlerAsync(Exception ex, ExceptionType exT = ExceptionType.UnhandledOther) + { + if (!IsEnabled) return; + ex.Data[Mechanism.HandledKey] = exT == ExceptionType.Handled; + if (exT == ExceptionType.UnhandledXaml) + ex.Data[Mechanism.MechanismKey] = "Application.XamlUnhandledException"; + SentrySdk.CaptureException(ex); + await SentrySdk.FlushAsync(TimeSpan.FromSeconds(1)); + } + + private static Exception? _exHLoopLastEx; + + // ReSharper disable once AsyncVoidMethod + /// + /// Clean loop last exception data to be cleaned after 20s so the exception data will be sent to Dsn again. + /// + private static async void ExHLoopLastEx_AutoClean() + { + await Task.Delay(20000); + if (_exHLoopLastEx == null) return; + lock (_exHLoopLastEx) + { + _exHLoopLastEx = null; + } + } + + public static void ExceptionHandler_ForLoop(Exception ex, ExceptionType exT = ExceptionType.UnhandledOther) + { + if (!IsEnabled) return; + if (ex == _exHLoopLastEx) return; + _exHLoopLastEx = ex; + ExHLoopLastEx_AutoClean(); + + ex.Data[Mechanism.HandledKey] = exT == ExceptionType.Handled; + SentrySdk.CaptureException(ex); + SentrySdk.FlushAsync(TimeSpan.FromSeconds(1)); + } + + } +} \ No newline at end of file diff --git a/Hi3Helper.Core/Classes/Shared/Region/LauncherConfig.cs b/Hi3Helper.Core/Classes/Shared/Region/LauncherConfig.cs index f696e7f46..2db7804aa 100644 --- a/Hi3Helper.Core/Classes/Shared/Region/LauncherConfig.cs +++ b/Hi3Helper.Core/Classes/Shared/Region/LauncherConfig.cs @@ -408,10 +408,7 @@ public static Guid GetGuid(int sessionNum) #else { "EnableConsole", false }, #endif - #if USEREMOTELOGGING { "SendRemoteCrashData", true }, - #endif - { "SendRemoteCrashData", false }, { "EnableMultipleInstance", false }, { "DontAskUpdate", false }, { "ThemeMode", new IniValue(AppThemeMode.Default) }, From fb444ae7a120b2cb3ff9ff825a3117a76db735c1 Mon Sep 17 00:00:00 2001 From: Bagus Nur Listiyono Date: Sat, 9 Nov 2024 18:08:11 +0700 Subject: [PATCH 08/33] Catch ImageLoaderHelper download exceptions --- CollapseLauncher/Classes/Helper/Image/ImageLoaderHelper.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/CollapseLauncher/Classes/Helper/Image/ImageLoaderHelper.cs b/CollapseLauncher/Classes/Helper/Image/ImageLoaderHelper.cs index 1f8b01f2c..8612cf7ea 100644 --- a/CollapseLauncher/Classes/Helper/Image/ImageLoaderHelper.cs +++ b/CollapseLauncher/Classes/Helper/Image/ImageLoaderHelper.cs @@ -527,13 +527,11 @@ public static async ValueTask TryDownloadToCompleteness(string url, FileInfo fil // Ignore cancellation exceptions catch (TaskCanceledException) { } catch (OperationCanceledException) { } -#if !DEBUG catch (Exception ex) { // ErrorSender.SendException(ex, ErrorType.Connection); Logger.LogWriteLine($"Error has occured while downloading in background for: {url}\r\n{ex}", LogType.Error, true); } -#endif finally { ArrayPool.Shared.Return(buffer); From 105da5374913d850463c2633414fb655afdc5a42 Mon Sep 17 00:00:00 2001 From: Bagus Nur Listiyono Date: Sat, 9 Nov 2024 18:08:34 +0700 Subject: [PATCH 09/33] Refactor Sentry toggle --- CollapseLauncher/App.xaml.cs | 4 +--- CollapseLauncher/Program.cs | 4 +--- .../XAMLs/MainApp/Pages/SettingsPage.xaml | 14 +++++++------- .../XAMLs/MainApp/Pages/SettingsPage.xaml.cs | 9 +++------ .../Classes/SentryHelper/SentryHelper.cs | 2 +- 5 files changed, 13 insertions(+), 20 deletions(-) diff --git a/CollapseLauncher/App.xaml.cs b/CollapseLauncher/App.xaml.cs index 880a72bf6..80e8e20b3 100644 --- a/CollapseLauncher/App.xaml.cs +++ b/CollapseLauncher/App.xaml.cs @@ -1,6 +1,7 @@ using CollapseLauncher.Helper; using CollapseLauncher.Helper.Image; using Hi3Helper; +using Hi3Helper.SentryHelper; using Hi3Helper.Shared.Region; using Microsoft.UI; using Microsoft.UI.Xaml; @@ -10,9 +11,6 @@ using System; using System.Linq; using Windows.UI; -using Hi3Helper.Core.SentryHelper; -using Sentry; -using Sentry.Protocol; using static CollapseLauncher.InnerLauncherConfig; using static Hi3Helper.InvokeProp; using static Hi3Helper.Logger; diff --git a/CollapseLauncher/Program.cs b/CollapseLauncher/Program.cs index 531e429cc..d0a076dea 100644 --- a/CollapseLauncher/Program.cs +++ b/CollapseLauncher/Program.cs @@ -1,7 +1,7 @@ using CollapseLauncher.Helper; using CollapseLauncher.Helper.Update; using Hi3Helper; -using Hi3Helper.Core.SentryHelper; +using Hi3Helper.SentryHelper; using Hi3Helper.Http.Legacy; using Hi3Helper.Shared.ClassStruct; using InnoSetupHelper; @@ -23,8 +23,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -using Sentry; -using Sentry.Infrastructure; using WinRT; using static CollapseLauncher.ArgumentParser; using static CollapseLauncher.InnerLauncherConfig; diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml b/CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml index e38138df7..2bc308423 100644 --- a/CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml +++ b/CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml @@ -1323,6 +1323,13 @@ + - GetAppConfigValue("SendRemoteCrashData").ToBool(); - set - { - SetAndSaveConfigValue("SendRemoteCrashData", value); - // TODO: Include some setup stuff here - } + get => SentryHelper.IsEnabled; + set => SentryHelper.IsEnabled = value; } private bool IsIntroEnabled diff --git a/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs b/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs index 4943e76bb..83d83f529 100644 --- a/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs +++ b/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs @@ -6,7 +6,7 @@ using Sentry.Protocol; #nullable enable -namespace Hi3Helper.Core.SentryHelper +namespace Hi3Helper.SentryHelper { public static class SentryHelper { From 421eefa9b6c209d571811e6b29f9262d7157a20e Mon Sep 17 00:00:00 2001 From: Bagus Nur Listiyono Date: Sat, 9 Nov 2024 18:13:07 +0700 Subject: [PATCH 10/33] Make sure to not send PII --- Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs b/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs index 83d83f529..5185bb8c3 100644 --- a/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs +++ b/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs @@ -51,19 +51,18 @@ public static void InitializeSentrySdk() o.DiagnosticLogger = new ConsoleDiagnosticLogger(SentryLevel.Debug); o.DiagnosticLevel = SentryLevel.Debug; #else - o.Debug = false; + o.Debug = false; #endif o.TracesSampleRate = 1.0; o.IsGlobalModeEnabled = true; o.DisableWinUiUnhandledExceptionIntegration(); // Use this for trimmed/NativeAOT published app o.StackTraceMode = StackTraceMode.Enhanced; - + o.SendDefaultPii = false; #if DEBUG o.Distribution = "Debug"; #else o.Distribution = IsPreview ? "Preview" : "Stable"; #endif - o.MaxAttachmentSize = 5 * 1024 * 1024; // 5 MB }); } From 24a6123ca54eb17f3b01c9a4f879adfa49c88612 Mon Sep 17 00:00:00 2001 From: Bagus Nur Listiyono Date: Sat, 9 Nov 2024 18:22:09 +0700 Subject: [PATCH 11/33] Add dedup and attachment flags This added current log for when exception is sent to Dsn --- Hi3Helper.Core/Classes/Logger/LoggerBase.cs | 2 ++ Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/Hi3Helper.Core/Classes/Logger/LoggerBase.cs b/Hi3Helper.Core/Classes/Logger/LoggerBase.cs index 8dd55298a..a1d822319 100644 --- a/Hi3Helper.Core/Classes/Logger/LoggerBase.cs +++ b/Hi3Helper.Core/Classes/Logger/LoggerBase.cs @@ -18,6 +18,7 @@ public class LoggerBase private string _logFolder { get; set; } #if !APPLYUPDATE private string _logPath { get; set; } + public static string LogPath; #endif private StringBuilder _stringBuilder { get; set; } #endregion @@ -224,6 +225,7 @@ private void InitializeWriter(bool isFallback, Encoding logEncoding) // Append the current instance number fallbackString += $"-id{GetTotalInstance()}"; _logPath = Path.Combine(_logFolder, $"log-{dateString + fallbackString}.log"); + LogPath = _logPath; // Initialize _logWriter to the given _logPath. // The FileShare.ReadWrite is still being used to avoid potential conflict if the launcher needs diff --git a/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs b/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs index 5185bb8c3..2f9533839 100644 --- a/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs +++ b/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs @@ -64,6 +64,12 @@ public static void InitializeSentrySdk() o.Distribution = IsPreview ? "Preview" : "Stable"; #endif o.MaxAttachmentSize = 5 * 1024 * 1024; // 5 MB + o.DeduplicateMode = DeduplicateMode.All; + }); + + SentrySdk.ConfigureScope(s => + { + s.AddAttachment(LoggerBase.LogPath); }); } From ff0786090dd51bdb1207e341b5ef5ab48d63f7e6 Mon Sep 17 00:00:00 2001 From: Bagus Nur Listiyono Date: Sun, 10 Nov 2024 00:58:33 +0700 Subject: [PATCH 12/33] weeeeeeeeeeeee 1. Redacted username in the log file when its not debug build 2. Properly dispose SentrySdk when toggled off 3. Pipe SentrySdk log to Logger 4. Use correct flusher for SentryHelper.cs 5. Fixed cleaner loop for ExceptionHandler_ForLoop by @neon-nyan Co-authored-by: Kemal Setya Adhi --- CollapseLauncher/Program.cs | 10 ++- Hi3Helper.Core/Classes/Logger/LoggerBase.cs | 4 +- .../SentryHelper/SentryEventProcessor.cs | 17 ++++ .../Classes/SentryHelper/SentryHelper.cs | 83 ++++++++++++++----- 4 files changed, 86 insertions(+), 28 deletions(-) create mode 100644 Hi3Helper.Core/Classes/SentryHelper/SentryEventProcessor.cs diff --git a/CollapseLauncher/Program.cs b/CollapseLauncher/Program.cs index d0a076dea..c66ce0f9f 100644 --- a/CollapseLauncher/Program.cs +++ b/CollapseLauncher/Program.cs @@ -81,6 +81,7 @@ public static void Main(params string[] args) } + SentryHelper.IsPreview = IsPreview; if (SentryHelper.IsEnabled) { try @@ -93,10 +94,7 @@ public static void Main(params string[] args) } catch (Exception ex) { - LogWriteLine("Failed to load Sentry SDK.", LogType.Sentry, true); -#if DEBUG - LogWriteLine(ex.Message, LogType.Debug, true); -#endif + LogWriteLine($"Failed to load Sentry SDK.\r\n{ex}", LogType.Sentry, true); } } @@ -105,7 +103,11 @@ public static void Main(params string[] args) LogWriteLine(string.Format("Running Collapse Launcher [{0}], [{3}], under {1}, as {2}", LauncherUpdateHelper.LauncherCurrentVersionString, GetVersionString(), + #if DEBUG Environment.UserName, + #else + "[REDACTED]", + #endif IsPreview ? "Preview" : "Stable"), LogType.Scheme, true); var winAppSDKVer = FileVersionInfo.GetVersionInfo("Microsoft.ui.xaml.dll"); diff --git a/Hi3Helper.Core/Classes/Logger/LoggerBase.cs b/Hi3Helper.Core/Classes/Logger/LoggerBase.cs index a1d822319..eb6a812d1 100644 --- a/Hi3Helper.Core/Classes/Logger/LoggerBase.cs +++ b/Hi3Helper.Core/Classes/Logger/LoggerBase.cs @@ -18,7 +18,7 @@ public class LoggerBase private string _logFolder { get; set; } #if !APPLYUPDATE private string _logPath { get; set; } - public static string LogPath; + public static string LogPath { get; set; } #endif private StringBuilder _stringBuilder { get; set; } #endregion @@ -277,7 +277,7 @@ private void InitializeWriter(bool isFallback, Encoding logEncoding) LogType.Game => "[Game] ", LogType.Debug => "[DBG] ", LogType.GLC => "[GLC] ", - LogType.Sentry => "[Remo] ", + LogType.Sentry => "[Sentry] ", LogType.NoTag => " ", _ => throw ThrowInvalidType() }; diff --git a/Hi3Helper.Core/Classes/SentryHelper/SentryEventProcessor.cs b/Hi3Helper.Core/Classes/SentryHelper/SentryEventProcessor.cs new file mode 100644 index 000000000..92394665d --- /dev/null +++ b/Hi3Helper.Core/Classes/SentryHelper/SentryEventProcessor.cs @@ -0,0 +1,17 @@ +using Sentry; +using Sentry.Extensibility; +using static Hi3Helper.Logger; + +namespace Hi3Helper.SentryHelper +{ + #nullable enable + public class SentryEventProcessor : ISentryEventProcessor + { + public SentryEvent? Process(SentryEvent @event) + { + var log = $"Sentry event caught! ID: {@event.EventId}, Level: {@event.Level}\r\n{@event.Message?.Formatted}"; + LogWriteLine(log, LogType.Sentry, true); // Use our logger + return @event; // Pipe em back up + } + } +} \ No newline at end of file diff --git a/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs b/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs index 2f9533839..af90cc9ad 100644 --- a/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs +++ b/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs @@ -1,6 +1,8 @@ using Sentry; using Sentry.Infrastructure; using System; +using System.IO; +using System.Threading; using System.Threading.Tasks; using Hi3Helper.Shared.Region; using Sentry.Protocol; @@ -38,21 +40,28 @@ public static bool IsEnabled LauncherConfig.SetAndSaveConfigValue("SendRemoteCrashData", value); } } - - + + public static bool IsPreview { get; set; } + + private static IDisposable? _sentryInstance; public static void InitializeSentrySdk() { - SentrySdk.Init(o => + _sentryInstance = SentrySdk.Init(o => { o.Dsn = "https://2acc39f86f2b4f5a99bac09494af13c6@bugsink.bagelnl.my.id/1"; + o.AddEventProcessor(new SentryEventProcessor()); #if DEBUG o.Debug = true; - o.DiagnosticLogger = new ConsoleDiagnosticLogger(SentryLevel.Debug); + o.DiagnosticLogger = new ConsoleAndTraceDiagnosticLogger(SentryLevel.Debug); o.DiagnosticLevel = SentryLevel.Debug; #else o.Debug = false; + o.DiagnosticLevel = SentryLevel.Error; #endif + o.AutoSessionTracking = true; + o.StackTraceMode = StackTraceMode.Enhanced; + o.DisableSystemDiagnosticsMetricsIntegration(); o.TracesSampleRate = 1.0; o.IsGlobalModeEnabled = true; o.DisableWinUiUnhandledExceptionIntegration(); // Use this for trimmed/NativeAOT published app @@ -63,17 +72,35 @@ public static void InitializeSentrySdk() #else o.Distribution = IsPreview ? "Preview" : "Stable"; #endif - o.MaxAttachmentSize = 5 * 1024 * 1024; // 5 MB + o.MaxAttachmentSize = 2 * 1024 * 1024; // 2 MB o.DeduplicateMode = DeduplicateMode.All; }); SentrySdk.ConfigureScope(s => { - s.AddAttachment(LoggerBase.LogPath); + // Broken atm due to length = 0 + // dunno why + s.AddAttachment(LoggerBase.LogPath, AttachmentType.Default, "text/plain"); }); } - private static void StopSentrySdk() => SentrySdk.EndSession(); + private static void StopSentrySdk() + { + try + { + SentrySdk.Flush(TimeSpan.FromSeconds(5)); + SentrySdk.EndSession(); + } + catch (Exception ex) + { + Logger.LogWriteLine($"Failed when preparing to stop SentryInstance, Dispose will still be invoked!\r\n{ex}" + , LogType.Error, true); + } + finally + { + _sentryInstance?.Dispose(); + } + } public static void InitializeExceptionRedirect() { @@ -85,15 +112,15 @@ public static void InitializeExceptionRedirect() if (ex == null) return; ex.Data[Mechanism.HandledKey] = false; ex.Data[Mechanism.MechanismKey] = "Application.UnhandledException"; - SentrySdk.CaptureException(ex); - SentrySdk.FlushAsync(TimeSpan.FromSeconds(1)).GetAwaiter().GetResult(); + ExceptionHandler(ex, ExceptionType.UnhandledOther); + + throw ex; }; TaskScheduler.UnobservedTaskException += (_, args) => { - SentrySdk.CaptureException(args.Exception); - SentrySdk.FlushAsync(TimeSpan.FromSeconds(1)).GetAwaiter().GetResult(); - args.SetObserved(); + args.Exception.Data[Mechanism.HandledKey] = false; + ExceptionHandler(args.Exception, ExceptionType.UnhandledOther); }; } @@ -102,17 +129,17 @@ public static void InitializeExceptionRedirect() /// /// /// - public static void ExceptionHandler(Exception ex, ExceptionType exT = ExceptionType.UnhandledOther) + public static void ExceptionHandler(Exception ex, ExceptionType exT = ExceptionType.Handled) { if (!IsEnabled) return; ex.Data[Mechanism.HandledKey] = exT == ExceptionType.Handled; if (exT == ExceptionType.UnhandledXaml) ex.Data[Mechanism.MechanismKey] = "Application.XamlUnhandledException"; SentrySdk.CaptureException(ex); - SentrySdk.FlushAsync(TimeSpan.FromSeconds(1)).GetAwaiter().GetResult(); + SentrySdk.Flush(TimeSpan.FromSeconds(5)); } - public static async Task ExceptionHandlerAsync(Exception ex, ExceptionType exT = ExceptionType.UnhandledOther) + public static async Task ExceptionHandlerAsync(Exception ex, ExceptionType exT = ExceptionType.Handled) { if (!IsEnabled) return; ex.Data[Mechanism.HandledKey] = exT == ExceptionType.Handled; @@ -123,6 +150,7 @@ public static async Task ExceptionHandlerAsync(Exception ex, ExceptionType exT = } private static Exception? _exHLoopLastEx; + private static CancellationTokenSource _loopToken = new(); // ReSharper disable once AsyncVoidMethod /// @@ -130,25 +158,36 @@ public static async Task ExceptionHandlerAsync(Exception ex, ExceptionType exT = /// private static async void ExHLoopLastEx_AutoClean() { - await Task.Delay(20000); - if (_exHLoopLastEx == null) return; - lock (_exHLoopLastEx) + // if (loopToken.Token.IsCancellationRequested) return; + try + { + var t = _loopToken.Token; + await Task.Delay(20000, t); + if (_exHLoopLastEx == null) return; + + lock (_exHLoopLastEx) + { + _exHLoopLastEx = null; + } + } + catch (TaskCanceledException) { - _exHLoopLastEx = null; + //ignore } } - public static void ExceptionHandler_ForLoop(Exception ex, ExceptionType exT = ExceptionType.UnhandledOther) + public static void ExceptionHandler_ForLoop(Exception ex, ExceptionType exT = ExceptionType.Handled) { if (!IsEnabled) return; if (ex == _exHLoopLastEx) return; + _loopToken.Cancel(); + _loopToken = new CancellationTokenSource(); _exHLoopLastEx = ex; ExHLoopLastEx_AutoClean(); ex.Data[Mechanism.HandledKey] = exT == ExceptionType.Handled; SentrySdk.CaptureException(ex); - SentrySdk.FlushAsync(TimeSpan.FromSeconds(1)); + SentrySdk.Flush(TimeSpan.FromSeconds(5)); } - } } \ No newline at end of file From 115ab82ba34421297ce5edc0014ad3bdab5969a3 Mon Sep 17 00:00:00 2001 From: Bagus Nur Listiyono Date: Sun, 10 Nov 2024 00:59:40 +0700 Subject: [PATCH 13/33] Pipe exceptions coming from EventsHandler.SendException No need for adding Sentry's ExceptionHandler on catcher that has SendException already --- .../Classes/EventsManagement/EventsHandler.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CollapseLauncher/Classes/EventsManagement/EventsHandler.cs b/CollapseLauncher/Classes/EventsManagement/EventsHandler.cs index 2942a6a44..f41d1b4f1 100644 --- a/CollapseLauncher/Classes/EventsManagement/EventsHandler.cs +++ b/CollapseLauncher/Classes/EventsManagement/EventsHandler.cs @@ -8,6 +8,7 @@ using System.Text.Json.Serialization; using Windows.Foundation; using Windows.Networking.Connectivity; +using Hi3Helper.SentryHelper; using static CollapseLauncher.InnerLauncherConfig; using static Hi3Helper.Locale; using static Hi3Helper.Shared.Region.LauncherConfig; @@ -133,7 +134,12 @@ internal static class ErrorSender public static ErrorType ExceptionType; public static string ExceptionTitle; public static string ExceptionSubtitle; - public static void SendException(Exception e, ErrorType eT = ErrorType.Unhandled) => invoker!.SendException(e, eT); + + public static void SendException(Exception e, ErrorType eT = ErrorType.Unhandled) + { + SentryHelper.ExceptionHandler(e); + invoker!.SendException(e, eT); + } public static void SendWarning(Exception e, ErrorType eT = ErrorType.Warning) => invoker!.SendException(e, eT); public static void SendExceptionWithoutPage(Exception e, ErrorType eT = ErrorType.Unhandled) From 101f937d1a8b20868528286099e3eafabca34a80 Mon Sep 17 00:00:00 2001 From: Ron Friedman Date: Sun, 10 Nov 2024 22:02:46 -0500 Subject: [PATCH 14/33] add sentry logging to some exceptions --- CollapseLauncher/App.xaml.cs | 1 + .../CachesManagement/StarRail/Check.cs | 2 ++ .../PersonalGraphicsSettingV2.cs | 2 ++ .../StarRail/RegistryClass/Model.cs | 2 ++ .../Background/BackgroundMediaUtility.cs | 2 ++ .../RegionManagement/FallbackCDNUtil.cs | 20 ++++++++++++------- .../XAMLs/MainApp/MainPage.xaml.cs | 12 +++++++++-- .../XAMLs/MainApp/Pages/UpdatePage.xaml.cs | 7 +++++-- 8 files changed, 37 insertions(+), 11 deletions(-) diff --git a/CollapseLauncher/App.xaml.cs b/CollapseLauncher/App.xaml.cs index 80e8e20b3..98fe54b4b 100644 --- a/CollapseLauncher/App.xaml.cs +++ b/CollapseLauncher/App.xaml.cs @@ -139,6 +139,7 @@ protected override void OnLaunched(LaunchActivatedEventArgs args) { LogWriteLine($"FATAL ERROR ON APP INITIALIZER LEVEL!!!\r\n{ex}", LogType.Error, true); LogWriteLine("\r\nIf this is not intended, please report it to: https://github.com/CollapseLauncher/Collapse/issues\r\nPress any key to exit..."); + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); //Console.ReadLine(); throw; } diff --git a/CollapseLauncher/Classes/CachesManagement/StarRail/Check.cs b/CollapseLauncher/Classes/CachesManagement/StarRail/Check.cs index d78c9ea7c..47385f359 100644 --- a/CollapseLauncher/Classes/CachesManagement/StarRail/Check.cs +++ b/CollapseLauncher/Classes/CachesManagement/StarRail/Check.cs @@ -1,5 +1,6 @@ using Hi3Helper; using Hi3Helper.EncTool.Parser.AssetMetadata.SRMetadataAsset; +using Hi3Helper.SentryHelper; using System; using System.Collections.Generic; using System.IO; @@ -64,6 +65,7 @@ private async Task> Check(List assetIndex, CancellationTo } catch (AggregateException ex) { + await SentryHelper.ExceptionHandlerAsync(ex); throw ex.Flatten().InnerExceptions.First(); } diff --git a/CollapseLauncher/Classes/GameManagement/GameSettings/Honkai/RegistryClass/PersonalGraphicsSettingV2.cs b/CollapseLauncher/Classes/GameManagement/GameSettings/Honkai/RegistryClass/PersonalGraphicsSettingV2.cs index c9c9a4f6e..c6994564a 100644 --- a/CollapseLauncher/Classes/GameManagement/GameSettings/Honkai/RegistryClass/PersonalGraphicsSettingV2.cs +++ b/CollapseLauncher/Classes/GameManagement/GameSettings/Honkai/RegistryClass/PersonalGraphicsSettingV2.cs @@ -3,6 +3,7 @@ using CollapseLauncher.Interfaces; using Hi3Helper; using Hi3Helper.EncTool; +using Hi3Helper.SentryHelper; using Microsoft.Win32; using System; using System.Text; @@ -224,6 +225,7 @@ public void Save() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Failed to save {_ValueName}!\r\n{ex}", LogType.Error, true); } } diff --git a/CollapseLauncher/Classes/GameManagement/GameSettings/StarRail/RegistryClass/Model.cs b/CollapseLauncher/Classes/GameManagement/GameSettings/StarRail/RegistryClass/Model.cs index 0007a6f1e..b7e3536fa 100644 --- a/CollapseLauncher/Classes/GameManagement/GameSettings/StarRail/RegistryClass/Model.cs +++ b/CollapseLauncher/Classes/GameManagement/GameSettings/StarRail/RegistryClass/Model.cs @@ -3,6 +3,7 @@ using CollapseLauncher.Pages; using Hi3Helper; using Hi3Helper.EncTool; +using Hi3Helper.SentryHelper; using Microsoft.Win32; using System; using System.Collections.Generic; @@ -349,6 +350,7 @@ public void Save() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Failed to save {_ValueName}!\r\n{ex}", LogType.Error, true); } } diff --git a/CollapseLauncher/Classes/Helper/Background/BackgroundMediaUtility.cs b/CollapseLauncher/Classes/Helper/Background/BackgroundMediaUtility.cs index 909cf6302..e75dde7cd 100644 --- a/CollapseLauncher/Classes/Helper/Background/BackgroundMediaUtility.cs +++ b/CollapseLauncher/Classes/Helper/Background/BackgroundMediaUtility.cs @@ -1,5 +1,6 @@ using CollapseLauncher.Extension; using CollapseLauncher.Helper.Background.Loaders; +using Hi3Helper.SentryHelper; using Hi3Helper.Shared.Region; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; @@ -416,6 +417,7 @@ private async Task LoadBackgroundInner(string mediaPath, bool } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); if (throwAction != null) throwAction(ex); } diff --git a/CollapseLauncher/Classes/RegionManagement/FallbackCDNUtil.cs b/CollapseLauncher/Classes/RegionManagement/FallbackCDNUtil.cs index 8b9b283bf..a24e5357c 100644 --- a/CollapseLauncher/Classes/RegionManagement/FallbackCDNUtil.cs +++ b/CollapseLauncher/Classes/RegionManagement/FallbackCDNUtil.cs @@ -3,6 +3,7 @@ using Hi3Helper.Data; using Hi3Helper.Http; using Hi3Helper.Http.Legacy; +using Hi3Helper.SentryHelper; using Hi3Helper.Shared.Region; using System; using System.Diagnostics; @@ -47,15 +48,20 @@ public async Task DownloadFile(string url, string targetFile, Action progre try { FallbackCDNUtil.DownloadProgress += progressEvent; - await FallbackCDNUtil.DownloadCDNFallbackContent(downloadClient, targetFile, AppCurrentDownloadThread, GetRelativePathOnly(url), -#if !USEVELOPACK + await FallbackCDNUtil.DownloadCDNFallbackContent(downloadClient, targetFile, AppCurrentDownloadThread, + GetRelativePathOnly(url), + #if !USEVELOPACK default -#else - cancelToken -#endif - ); + #else + cancelToken + #endif + ); + } + catch (Exception ex) + { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); + throw; } - catch { throw; } finally { FallbackCDNUtil.DownloadProgress -= progressEvent; diff --git a/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs b/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs index 5ea06643b..7ae982d13 100644 --- a/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs +++ b/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs @@ -13,6 +13,7 @@ using CollapseLauncher.Statics; using CommunityToolkit.WinUI; using Hi3Helper; +using Hi3Helper.SentryHelper; using Hi3Helper.Shared.ClassStruct; using InnoSetupHelper; using Microsoft.UI; @@ -423,6 +424,7 @@ public static async Task CheckForAdminAccess(UIElement root) } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Restarting the launcher can't be completed! {ex}", LogType.Error, true); } break; @@ -658,6 +660,7 @@ private async void RunBackgroundCheck() } catch (JsonException ex) { + SentryHelper.ExceptionHandler(ex); LogWriteLine($"Error while trying to get Notification Feed or Metadata Update\r\n{ex}", LogType.Error, true); } catch (Exception ex) @@ -706,6 +709,7 @@ private async Task FetchNotificationFeed() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Failed to load notification push!\r\n{ex}", LogType.Warning, true); } } @@ -839,6 +843,7 @@ private void SpawnAppUpdatedNotification() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Something wrong while opening the \"unins000.dat\" or deleting the \"_NeedInnoLogUpdate\" file\r\n{ex}", LogType.Error, true); } } @@ -1699,6 +1704,7 @@ private void SpawnWebView2Panel(Uri URL) } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex); LogWriteLine($"Error while initialize EdgeWebView2. Opening browser instead!\r\n{ex}", LogType.Error, true); new Process { @@ -1802,7 +1808,7 @@ private void CreateKeyboardShortcutHandlers() { "CacheFolder", OpenGameCacheFolder_Invoked }, { "ForceCloseGame", ForceCloseGame_Invoked }, - { "RepairPage", GoGameRepir_Invoked }, + { "RepairPage", GoGameRepair_Invoked }, { "GameSettingsPage", GoGameSettings_Invoked }, { "CachesPage", GoGameCaches_Invoked }, @@ -1825,6 +1831,7 @@ private void CreateKeyboardShortcutHandlers() } catch (Exception error) { + SentryHelper.ExceptionHandler(error); LogWriteLine(error.ToString()); KbShortcutList = null; CreateKeyboardShortcutHandlers(); @@ -2068,10 +2075,11 @@ private void ForceCloseGame_Invoked(KeyboardAccelerator sender, KeyboardAccelera } catch (Win32Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"There is a problem while trying to stop Game with Region: {gamePreset.ZoneName}\r\nTraceback: {ex}", LogType.Error, true); } } - private void GoGameRepir_Invoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args) + private void GoGameRepair_Invoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args) { if (!(IsLoadRegionComplete) || CannotUseKbShortcuts) return; diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/UpdatePage.xaml.cs b/CollapseLauncher/XAMLs/MainApp/Pages/UpdatePage.xaml.cs index 6b723f19a..013296932 100644 --- a/CollapseLauncher/XAMLs/MainApp/Pages/UpdatePage.xaml.cs +++ b/CollapseLauncher/XAMLs/MainApp/Pages/UpdatePage.xaml.cs @@ -1,6 +1,7 @@ using CollapseLauncher.Helper.Update; using CommunityToolkit.Labs.WinUI.Labs.MarkdownTextBlock; using Hi3Helper; +using Hi3Helper.SentryHelper; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; #if !USEVELOPACK @@ -63,8 +64,9 @@ private async void LoadedAsyncRoutine(object sender, RoutedEventArgs e) await StartUpdateRoutine(); } - catch (TaskCanceledException) + catch (TaskCanceledException tce) { + await SentryHelper.ExceptionHandlerAsync(tce); Logger.LogWriteLine("Update countdown has been cancelled!", LogType.Default, true); } catch (Exception ex) @@ -99,8 +101,9 @@ private async Task StartUpdateRoutine() await _StartUpdateRoutine(); } - catch (OperationCanceledException) + catch (OperationCanceledException oce) { + await SentryHelper.ExceptionHandlerAsync(oce); Logger.LogWriteLine("Update has been canceled!", LogType.Warning, true); } catch (Exception ex) From 95a23b6a12223dee7e05ba7379f0eb5ed29b3bed Mon Sep 17 00:00:00 2001 From: Ron Friedman Date: Sun, 10 Nov 2024 23:17:49 -0500 Subject: [PATCH 15/33] finish adding sentry logging to base project Note: - Some submodules cannot import SentryHelper, which is in `Hi3Helper.Core` - Some calls are asynchronous, mostly for the handled exceptions, but also where it felt best to use them, feel free to change them if needed - Most are categorized as `UnhandledOther`, but if we feel the need to change some, we can, it simply affects tagging on the frontend dashboard. --- .../Background/BackgroundMediaUtility.cs | 2 +- .../Classes/Helper/Metadata/PresetConfig.cs | 13 +++- .../BaseClass/GameInstallPackage.cs | 2 + .../BaseClass/InstallManagerBase.cs | 31 +++++++-- .../Classes/RepairManagement/Genshin/Check.cs | 5 +- .../Classes/RepairManagement/Honkai/Check.cs | 6 +- .../Classes/RepairManagement/Honkai/Fetch.cs | 2 + .../RepairManagement/StarRail/Check.cs | 8 ++- CollapseLauncher/Program.cs | 6 +- .../XAMLs/MainApp/MainPage.xaml.cs | 6 +- .../MainApp/Pages/Dialogs/SimpleDialogs.cs | 65 ++++++++++--------- .../XAMLs/MainApp/Pages/HomePage.xaml.cs | 52 +++++++++++---- .../XAMLs/MainApp/Pages/RepairPage.xaml.cs | 13 ++-- .../XAMLs/MainApp/Pages/SettingsPage.xaml.cs | 9 ++- .../XAMLs/MainApp/Pages/UpdatePage.xaml.cs | 1 + Hi3Helper.Core/Classes/Data/InvokeProp.cs | 9 ++- Hi3Helper.Core/Classes/Logger/LoggerBase.cs | 7 +- .../Classes/Shared/Region/LauncherConfig.cs | 3 +- Hi3Helper.Core/Lang/Localization.cs | 12 ++-- 19 files changed, 178 insertions(+), 74 deletions(-) diff --git a/CollapseLauncher/Classes/Helper/Background/BackgroundMediaUtility.cs b/CollapseLauncher/Classes/Helper/Background/BackgroundMediaUtility.cs index e75dde7cd..a2593b01f 100644 --- a/CollapseLauncher/Classes/Helper/Background/BackgroundMediaUtility.cs +++ b/CollapseLauncher/Classes/Helper/Background/BackgroundMediaUtility.cs @@ -417,7 +417,7 @@ private async Task LoadBackgroundInner(string mediaPath, bool } catch (Exception ex) { - SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); + await SentryHelper.ExceptionHandlerAsync(ex, SentryHelper.ExceptionType.UnhandledOther); if (throwAction != null) throwAction(ex); } diff --git a/CollapseLauncher/Classes/Helper/Metadata/PresetConfig.cs b/CollapseLauncher/Classes/Helper/Metadata/PresetConfig.cs index 486d81108..c7ba19dca 100644 --- a/CollapseLauncher/Classes/Helper/Metadata/PresetConfig.cs +++ b/CollapseLauncher/Classes/Helper/Metadata/PresetConfig.cs @@ -5,6 +5,7 @@ using Hi3Helper; using Hi3Helper.Data; using Hi3Helper.EncTool.Parser.AssetMetadata; +using Hi3Helper.SentryHelper; using Microsoft.Win32; using System; using System.Buffers; @@ -520,12 +521,14 @@ private int GetVoiceLanguageID_StarRail(string regPath) } catch (JsonException ex) { + SentryHelper.ExceptionHandler(ex); LogWriteLine($"System.Text.Json cannot deserialize language ID registry in this path: {regPath}\r\nFallback value will be used (2 / ja-jp).\r\n{ex}", LogType.Warning, true); return 2; } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex); LogWriteLine($"Launcher cannot evaluate an existing language ID registry on {regPath}\r\nFallback value will be used (2 / ja-jp).\r\n{ex}", LogType.Warning, true); return 2; @@ -554,12 +557,14 @@ private int GetVoiceLanguageID_Genshin(string regPath) } catch (JsonException ex) { + SentryHelper.ExceptionHandler(ex); LogWriteLine($"System.Text.Json cannot deserialize language ID registry in this path: {regPath}\r\nFallback value will be used (2 / ja-jp).\r\n{ex}", LogType.Warning, true); return 2; } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex); LogWriteLine($"Launcher cannot evaluate an existing language ID registry on {regPath}\r\nFallback value will be used (2 / ja-jp).\r\n{ex}", LogType.Warning, true); return 2; @@ -645,6 +650,7 @@ private void SetVoiceLanguageID_Genshin(int langID) } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Cannot save voice language ID: {langID} to the registry!\r\n{ex}", LogType.Error, true); } } @@ -661,6 +667,7 @@ private void SetVoiceLanguageID_StarRail(int langID) } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Cannot save voice language ID: {langID} to the registry!\r\n{ex}", LogType.Error, true); } } @@ -741,6 +748,7 @@ public int GetRegServerNameID() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex); LogWriteLine($"Error while getting existing GENERAL_DATA_h2389025596 value on {ZoneFullname}! Returning value 0 as fallback!\r\nValue: {regValue}\r\n{ex}", LogType.Warning, true); return 0; @@ -764,9 +772,10 @@ public bool CheckExistingGame() return TryCheckGameLocation(value); } } - catch (Exception e) + catch (Exception ex) { - LogWriteLine($"{e}", LogType.Error, true); + SentryHelper.ExceptionHandler(ex); + LogWriteLine($"{ex}", LogType.Error, true); return false; } } diff --git a/CollapseLauncher/Classes/InstallManagement/BaseClass/GameInstallPackage.cs b/CollapseLauncher/Classes/InstallManagement/BaseClass/GameInstallPackage.cs index 8e6546f62..66b9705fd 100644 --- a/CollapseLauncher/Classes/InstallManagement/BaseClass/GameInstallPackage.cs +++ b/CollapseLauncher/Classes/InstallManagement/BaseClass/GameInstallPackage.cs @@ -3,6 +3,7 @@ using Hi3Helper.EncTool; using Hi3Helper.Http.Legacy; using Hi3Helper.Preset; +using Hi3Helper.SentryHelper; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -264,6 +265,7 @@ public void DeleteFile(int count) } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); Logger.LogWriteLine($"Failed while deleting file: {lastFile}. Skipping!\r\n{ex}", LogType.Warning, true); } } diff --git a/CollapseLauncher/Classes/InstallManagement/BaseClass/InstallManagerBase.cs b/CollapseLauncher/Classes/InstallManagement/BaseClass/InstallManagerBase.cs index a48de6f4f..fdac63b6b 100644 --- a/CollapseLauncher/Classes/InstallManagement/BaseClass/InstallManagerBase.cs +++ b/CollapseLauncher/Classes/InstallManagement/BaseClass/InstallManagerBase.cs @@ -63,6 +63,7 @@ using SophonManifest = Hi3Helper.Sophon.SophonManifest; using CollapseLauncher.Classes.FileDialogCOM; using CollapseLauncher.DiscordPresence; +using Hi3Helper.SentryHelper; // ReSharper disable ForCanBeConvertedToForeach // ReSharper disable SwitchStatementHandlesSomeKnownEnumValuesWithDefault @@ -169,6 +170,7 @@ protected bool _isSophonPreloadCompleted } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Error while deleting/creating sophon preload completion file! {ex}", LogType.Warning, true); } @@ -336,8 +338,10 @@ protected virtual async ValueTask ConfirmDeltaPatchDialog(DeltaPatchPropert await _gameRepairTool!.StartRepairRoutine(true)!; } } - catch + catch (Exception ex) + { + await SentryHelper.ExceptionHandlerAsync(ex); IsRunning = false; throw; } @@ -423,6 +427,7 @@ await Task.Run(() => } catch (Exception ex) { + await SentryHelper.ExceptionHandlerAsync(ex); LogWriteLine($"Error has occurred while performing delta-patch!\r\n{ex}", LogType.Error, true); throw; } @@ -1624,6 +1629,7 @@ protected virtual async Task StartPackageInstallationInner(List UninstallGame() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"An error occurred while deleting object {folderGameData}\r\n{ex}", LogType.Error, true); } @@ -2018,6 +2025,7 @@ public async ValueTask UninstallGame() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"An error occurred while deleting folder {folderNames}\r\n{ex}", LogType.Error, true); } @@ -2051,6 +2059,7 @@ public async ValueTask UninstallGame() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"An error occurred while deleting game AppData folder: {_gameVersionManager.GameDirAppDataPath}\r\n{ex}", LogType.Error, true); } @@ -2065,6 +2074,7 @@ public async ValueTask UninstallGame() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"An error occurred while deleting empty game folder: {GameFolder}\r\n{ex}", LogType.Error, true); } @@ -2077,6 +2087,7 @@ public async ValueTask UninstallGame() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Failed while uninstalling game: {_gameVersionManager.GameType} - Region: {_gameVersionManager.GamePreset.ZoneName}\r\n{ex}", LogType.Error, true); } @@ -2171,6 +2182,7 @@ await Parallel.ForEachAsync(EnumerateFileInfoAsync(token), token, (fileInfo, inn } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Failed deleting old file: {fileInfo.FullName}\r\n{ex}", LogType.Warning, true); } }, innerToken)); @@ -2228,6 +2240,7 @@ private async ValueTask FileHdiffPatcherInner(string patchPath, string sourceBas throw; // Otherwise, log the error + SentryHelper.ExceptionHandler(new InvalidDataException(), SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"New: {newFileSize} == Ref: {refFileSize}. File is already new. Skipping! {sourceBasePath}", LogType.Warning, true); } }, token); @@ -2279,14 +2292,16 @@ public virtual async ValueTask ApplyHdiffListPatch() await FileHdiffPatcherInner(patchPath, sourceBasePath, destPath, innerToken); } } - catch (OperationCanceledException) + catch (OperationCanceledException oce) { await _token.CancelAsync(); + await SentryHelper.ExceptionHandlerAsync(oce, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine("Cancelling patching process!...", LogType.Warning, true); throw; } catch (Exception ex) { + await SentryHelper.ExceptionHandlerAsync(ex); LogWriteLine($"Error while patching file: {entry.remoteName}. Skipping!\r\n{ex}", LogType.Warning, true); @@ -2314,6 +2329,7 @@ public virtual async ValueTask ApplyHdiffListPatch() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Failed while trying to delete temporary file: {destPath}, skipping!\r\n{ex}", LogType.Warning, true); } @@ -2335,7 +2351,9 @@ public virtual async ValueTask ApplyHdiffListPatch() } catch (AggregateException ex) { - throw ex.Flatten().InnerExceptions.First(); + var innerExceptionsFirst = ex.Flatten().InnerExceptions.First(); + SentryHelper.ExceptionHandler(innerExceptionsFirst, SentryHelper.ExceptionType.UnhandledOther); + throw innerExceptionsFirst; } finally { @@ -2433,6 +2451,7 @@ public virtual List TryGetHDiffList() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Error while parsing the size of the new file inside of diff: {filePath}\r\n{ex}", LogType.Warning, true); } @@ -2440,6 +2459,7 @@ public virtual List TryGetHDiffList() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Failed while trying to read hdiff file list: {listFile}\r\n{ex}", LogType.Warning, true); } @@ -2855,8 +2875,9 @@ private async Task StartSteamMigration(string gamePath) await gameRepairInstance.StartRepairRoutine(false); contentDialog.Hide(); } - catch (Exception) + catch (Exception ex) { + await SentryHelper.ExceptionHandlerAsync(ex, SentryHelper.ExceptionType.UnhandledOther); contentDialog.Hide(); throw; } @@ -3090,6 +3111,7 @@ private bool TryGetExistingBHI3LPath(ref string OutputPath) } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex); LogWriteLine($"Registry Value {_gameVersionManager.GamePreset.BetterHi3LauncherVerInfoReg}:\r\n{value}\r\n\r\nException:\r\n{ex}", LogType.Error, true); return false; @@ -3524,6 +3546,7 @@ private void TryRemoveRedundantHDiffList() } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Be careful that the installation process might have some problem since the launcher can't remove HDiff list file: {name}!\r\n{ex}", LogType.Warning, true); } diff --git a/CollapseLauncher/Classes/RepairManagement/Genshin/Check.cs b/CollapseLauncher/Classes/RepairManagement/Genshin/Check.cs index 4881606c2..a8d263e32 100644 --- a/CollapseLauncher/Classes/RepairManagement/Genshin/Check.cs +++ b/CollapseLauncher/Classes/RepairManagement/Genshin/Check.cs @@ -2,6 +2,7 @@ using Hi3Helper; using Hi3Helper.Data; using Hi3Helper.EncTool.Parser.AssetIndex; +using Hi3Helper.SentryHelper; using System; using System.Collections.Generic; using System.IO; @@ -51,7 +52,9 @@ private async Task Check(List assetIndex, CancellationToke } catch (AggregateException ex) { - throw ex.Flatten().InnerExceptions.First(); + var innerExceptionsFirst = ex.Flatten().InnerExceptions.First(); + SentryHelper.ExceptionHandler(innerExceptionsFirst, SentryHelper.ExceptionType.UnhandledOther); + throw innerExceptionsFirst; } // Re-add the asset index with a broken asset index diff --git a/CollapseLauncher/Classes/RepairManagement/Honkai/Check.cs b/CollapseLauncher/Classes/RepairManagement/Honkai/Check.cs index 06291a26d..c0dd49e73 100644 --- a/CollapseLauncher/Classes/RepairManagement/Honkai/Check.cs +++ b/CollapseLauncher/Classes/RepairManagement/Honkai/Check.cs @@ -1,6 +1,7 @@ using Hi3Helper; using Hi3Helper.Data; using Hi3Helper.EncTool.Parser.AssetMetadata; +using Hi3Helper.SentryHelper; using Hi3Helper.Shared.ClassStruct; using System; using System.Collections.Generic; @@ -73,7 +74,9 @@ private async Task Check(List assetIndex, CancellationToke } catch (AggregateException ex) { - throw ex.Flatten().InnerExceptions.First(); + var innerExceptionsFirst = ex.Flatten().InnerExceptions.First(); + SentryHelper.ExceptionHandler(innerExceptionsFirst, SentryHelper.ExceptionType.UnhandledOther); + throw innerExceptionsFirst; } // Re-add the asset index with a broken asset index @@ -650,6 +653,7 @@ private void GetUnusedAssetIndexList(List catalog, List assetIndex, CancellationToke } catch (AggregateException ex) { - throw ex.Flatten().InnerExceptions.First(); + var innerExceptionsFirst = ex.Flatten().InnerExceptions.First(); + SentryHelper.ExceptionHandler(innerExceptionsFirst, SentryHelper.ExceptionType.UnhandledOther); + throw innerExceptionsFirst; } // Re-add the asset index with a broken asset index @@ -297,8 +300,9 @@ private async ValueTask CheckAssetType(FilePropertiesRemote asset, List } catch (Exception ex) { + SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"[CheckRuntimeFeatures] Failed when enumerating available runtime features!\r\n{ex}", LogType.Error, true); } } diff --git a/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs b/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs index 7ae982d13..59f052d9e 100644 --- a/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs +++ b/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs @@ -424,7 +424,7 @@ public static async Task CheckForAdminAccess(UIElement root) } catch (Exception ex) { - SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); + await SentryHelper.ExceptionHandlerAsync(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Restarting the launcher can't be completed! {ex}", LogType.Error, true); } break; @@ -660,7 +660,7 @@ private async void RunBackgroundCheck() } catch (JsonException ex) { - SentryHelper.ExceptionHandler(ex); + await SentryHelper.ExceptionHandlerAsync(ex); LogWriteLine($"Error while trying to get Notification Feed or Metadata Update\r\n{ex}", LogType.Error, true); } catch (Exception ex) @@ -709,7 +709,7 @@ private async Task FetchNotificationFeed() } catch (Exception ex) { - SentryHelper.ExceptionHandler(ex, SentryHelper.ExceptionType.UnhandledOther); + await SentryHelper.ExceptionHandlerAsync(ex, SentryHelper.ExceptionType.UnhandledOther); LogWriteLine($"Failed to load notification push!\r\n{ex}", LogType.Warning, true); } } diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/Dialogs/SimpleDialogs.cs b/CollapseLauncher/XAMLs/MainApp/Pages/Dialogs/SimpleDialogs.cs index 9dffb3bb6..19d305636 100644 --- a/CollapseLauncher/XAMLs/MainApp/Pages/Dialogs/SimpleDialogs.cs +++ b/CollapseLauncher/XAMLs/MainApp/Pages/Dialogs/SimpleDialogs.cs @@ -9,6 +9,7 @@ using CollapseLauncher.Statics; using CommunityToolkit.WinUI; using Hi3Helper; +using Hi3Helper.SentryHelper; using Microsoft.UI.Input; using Microsoft.UI.Text; using Microsoft.UI.Xaml; @@ -1084,55 +1085,59 @@ public static async Task Dialog_ShowUnhandledExceptionMenu( try { string exceptionContent = ErrorSender.ExceptionContent; - string title = ErrorSender.ExceptionTitle; - string subtitle = ErrorSender.ExceptionSubtitle; + string title = ErrorSender.ExceptionTitle; + string subtitle = ErrorSender.ExceptionSubtitle; bool isShowBackButton = (ErrorSender.ExceptionType == ErrorType.Connection) && (WindowUtility.CurrentWindow as MainWindow).rootFrame.CanGoBack; Grid rootGrid = CollapseUIExt.CreateGrid() - .WithHorizontalAlignment(HorizontalAlignment.Stretch) - .WithVerticalAlignment(VerticalAlignment.Stretch) - .WithRows(GridLength.Auto, new(1, GridUnitType.Star), GridLength.Auto); + .WithHorizontalAlignment(HorizontalAlignment.Stretch) + .WithVerticalAlignment(VerticalAlignment.Stretch) + .WithRows(GridLength.Auto, new(1, GridUnitType.Star), GridLength.Auto); _ = rootGrid.AddElementToGridRow(new TextBlock { - Text = subtitle, + Text = subtitle, TextWrapping = TextWrapping.Wrap, - FontWeight = FontWeights.Medium + FontWeight = FontWeights.Medium }, 0); _ = rootGrid.AddElementToGridRow(new TextBox - { - IsReadOnly = true, - TextWrapping = TextWrapping.Wrap, - MaxHeight = 300, - AcceptsReturn = true, - Text = exceptionContent - }, 1).WithMargin(0d, 8d) - .WithHorizontalAlignment(HorizontalAlignment.Stretch) - .WithVerticalAlignment(VerticalAlignment.Stretch); + { + IsReadOnly = true, + TextWrapping = TextWrapping.Wrap, + MaxHeight = 300, + AcceptsReturn = true, + Text = exceptionContent + }, 1).WithMargin(0d, 8d) + .WithHorizontalAlignment(HorizontalAlignment.Stretch) + .WithVerticalAlignment(VerticalAlignment.Stretch); copyButton = rootGrid.AddElementToGridRow( - CollapseUIExt.CreateButtonWithIcon