From dc0531eb3882cc3e331ee24a9416adb912a1bc18 Mon Sep 17 00:00:00 2001 From: pizzaboxer Date: Sat, 1 Jul 2023 20:34:00 +0100 Subject: [PATCH] Add new exception dialog --- Bloxstrap/App.xaml.cs | 37 ++++++----- Bloxstrap/Logger.cs | 18 +++-- .../UI/BootstrapperDialogs/BaseFunctions.cs | 6 -- .../IBootstrapperDialog.cs | 1 - .../WPF/Views/ByfronDialog.xaml.cs | 2 - .../WPF/Views/FluentDialog.xaml.cs | 3 - .../WinForms/DialogBase.cs | 2 - .../WinForms/VistaDialog.cs | 30 --------- Bloxstrap/UI/Controls.cs | 12 +++- Bloxstrap/UI/ExceptionDialog.xaml | 49 ++++++++++++++ Bloxstrap/UI/ExceptionDialog.xaml.cs | 65 +++++++++++++++++++ 11 files changed, 159 insertions(+), 66 deletions(-) create mode 100644 Bloxstrap/UI/ExceptionDialog.xaml create mode 100644 Bloxstrap/UI/ExceptionDialog.xaml.cs diff --git a/Bloxstrap/App.xaml.cs b/Bloxstrap/App.xaml.cs index 4f52b588..8d93a46e 100644 --- a/Bloxstrap/App.xaml.cs +++ b/Bloxstrap/App.xaml.cs @@ -16,10 +16,10 @@ using Bloxstrap.Extensions; using Bloxstrap.Models; using Bloxstrap.Models.Attributes; +using Bloxstrap.UI; using Bloxstrap.UI.BootstrapperDialogs; using Bloxstrap.UI.MessageBox; using Bloxstrap.Utility; -using Bloxstrap.UI; namespace Bloxstrap { @@ -100,8 +100,17 @@ void GlobalExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs Logger.WriteLine("[App::OnStartup] An exception occurred when running the main thread"); Logger.WriteLine($"[App::OnStartup] {e.Exception}"); + FinalizeExceptionHandling(e.Exception); + } + + void FinalizeExceptionHandling(Exception exception) + { +#if DEBUG + throw exception; +#endif + if (!IsQuiet) - Settings.Prop.BootstrapperStyle.GetNew().ShowError($"{e.Exception.GetType()}: {e.Exception.Message}"); + Controls.ShowExceptionDialog(exception); Terminate(Bootstrapper.ERROR_INSTALL_FAILURE); } @@ -313,13 +322,9 @@ protected override void OnStartup(StartupEventArgs e) } } - // there's a bug here that i have yet to fix! - // sometimes the task just terminates when the bootstrapper hasn't - // actually finished, causing the bootstrapper to hang indefinitely - // i have no idea how the fuck this happens, but it happens like VERY - // rarely so i'm not too concerned by it - // maybe one day ill find out why it happens - Task bootstrapperTask = Task.Run(() => bootstrapper.Run()).ContinueWith(t => + Task bootstrapperTask = Task.Run(() => bootstrapper.Run()); + + bootstrapperTask.ContinueWith(t => { Logger.WriteLine("[App::OnStartup] Bootstrapper task has finished"); @@ -331,16 +336,18 @@ protected override void OnStartup(StartupEventArgs e) Logger.WriteLine($"[App::OnStartup] {t.Exception}"); -#if DEBUG - throw t.Exception; -#else - var exception = t.Exception.InnerExceptions.Count >= 1 ? t.Exception.InnerExceptions[0] : t.Exception; - dialog?.ShowError($"{exception.GetType()}: {exception.Message}"); - Terminate(Bootstrapper.ERROR_INSTALL_FAILURE); + Exception exception = t.Exception; + +#if !DEBUG + if (t.Exception.GetType().ToString() == "System.AggregateException") + exception = t.Exception.InnerException!; #endif + + FinalizeExceptionHandling(exception); }); dialog?.ShowBootstrapper(); + bootstrapperTask.Wait(); if (singletonMutex is not null) diff --git a/Bloxstrap/Logger.cs b/Bloxstrap/Logger.cs index 883dac25..d2f5f9cb 100644 --- a/Bloxstrap/Logger.cs +++ b/Bloxstrap/Logger.cs @@ -16,9 +16,12 @@ namespace Bloxstrap public class Logger { private readonly SemaphoreSlim _semaphore = new(1, 1); - private readonly List _backlog = new(); private FileStream? _filestream; + public readonly List Backlog = new(); + public bool Initialized = false; + public string? Filename; + public void Initialize(string filename) { if (_filestream is not null) @@ -31,10 +34,13 @@ public void Initialize(string filename) _filestream = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.Read); - if (_backlog.Count > 0) - WriteToLog(string.Join("\r\n", _backlog)); + if (Backlog.Count > 0) + WriteToLog(string.Join("\r\n", Backlog)); WriteLine($"[Logger::Logger] Initialized at {filename}"); + + Initialized = true; + Filename = filename; } public void WriteLine(string message) @@ -49,16 +55,16 @@ public void WriteLine(string message) private async void WriteToLog(string message) { - if (_filestream is null) + if (!Initialized) { - _backlog.Add(message); + Backlog.Add(message); return; } try { await _semaphore.WaitAsync(); - await _filestream.WriteAsync(Encoding.Unicode.GetBytes($"{message}\r\n")); + await _filestream!.WriteAsync(Encoding.Unicode.GetBytes($"{message}\r\n")); await _filestream.FlushAsync(); } finally diff --git a/Bloxstrap/UI/BootstrapperDialogs/BaseFunctions.cs b/Bloxstrap/UI/BootstrapperDialogs/BaseFunctions.cs index c7d096d1..3a89637b 100644 --- a/Bloxstrap/UI/BootstrapperDialogs/BaseFunctions.cs +++ b/Bloxstrap/UI/BootstrapperDialogs/BaseFunctions.cs @@ -14,11 +14,5 @@ public static void ShowSuccess(string message, Action? callback) App.Terminate(); } - - public static void ShowError(string message) - { - Controls.ShowMessageBox($"An error occurred while starting Roblox\n\nDetails: {message}", MessageBoxImage.Error); - App.Terminate(Bootstrapper.ERROR_INSTALL_FAILURE); - } } } diff --git a/Bloxstrap/UI/BootstrapperDialogs/IBootstrapperDialog.cs b/Bloxstrap/UI/BootstrapperDialogs/IBootstrapperDialog.cs index 8e4a4ec3..635b9125 100644 --- a/Bloxstrap/UI/BootstrapperDialogs/IBootstrapperDialog.cs +++ b/Bloxstrap/UI/BootstrapperDialogs/IBootstrapperDialog.cs @@ -15,6 +15,5 @@ public interface IBootstrapperDialog void ShowBootstrapper(); void CloseBootstrapper(); void ShowSuccess(string message, Action? callback = null); - void ShowError(string message); } } diff --git a/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/ByfronDialog.xaml.cs b/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/ByfronDialog.xaml.cs index 910f67e0..62911e6e 100644 --- a/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/ByfronDialog.xaml.cs +++ b/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/ByfronDialog.xaml.cs @@ -92,8 +92,6 @@ public ByfronDialog() public void CloseBootstrapper() => Dispatcher.BeginInvoke(this.Close); public void ShowSuccess(string message, Action? callback) => BaseFunctions.ShowSuccess(message, callback); - - public void ShowError(string message) => BaseFunctions.ShowError(message); #endregion } } diff --git a/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/FluentDialog.xaml.cs b/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/FluentDialog.xaml.cs index e7aba978..339248ee 100644 --- a/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/FluentDialog.xaml.cs +++ b/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/FluentDialog.xaml.cs @@ -86,10 +86,7 @@ public FluentDialog() public void CloseBootstrapper() => Dispatcher.BeginInvoke(this.Close); - // TODO: make prompts use dialog view natively rather than using message dialog boxes public void ShowSuccess(string message, Action? callback) => BaseFunctions.ShowSuccess(message, callback); - - public void ShowError(string message) => BaseFunctions.ShowError(message); #endregion } } diff --git a/Bloxstrap/UI/BootstrapperDialogs/WinForms/DialogBase.cs b/Bloxstrap/UI/BootstrapperDialogs/WinForms/DialogBase.cs index 23c6c549..253062c3 100644 --- a/Bloxstrap/UI/BootstrapperDialogs/WinForms/DialogBase.cs +++ b/Bloxstrap/UI/BootstrapperDialogs/WinForms/DialogBase.cs @@ -101,8 +101,6 @@ public virtual void CloseBootstrapper() } public virtual void ShowSuccess(string message, Action? callback) => BaseFunctions.ShowSuccess(message, callback); - - public virtual void ShowError(string message) => BaseFunctions.ShowError(message); #endregion } } diff --git a/Bloxstrap/UI/BootstrapperDialogs/WinForms/VistaDialog.cs b/Bloxstrap/UI/BootstrapperDialogs/WinForms/VistaDialog.cs index 211036f9..9be1ea36 100644 --- a/Bloxstrap/UI/BootstrapperDialogs/WinForms/VistaDialog.cs +++ b/Bloxstrap/UI/BootstrapperDialogs/WinForms/VistaDialog.cs @@ -109,36 +109,6 @@ public override void ShowSuccess(string message, Action? callback) } } - public override void ShowError(string message) - { - if (this.InvokeRequired) - { - this.Invoke(ShowError, message); - } - else - { - TaskDialogPage errorDialog = new() - { - Icon = TaskDialogIcon.Error, - Caption = App.Settings.Prop.BootstrapperTitle, - Heading = "An error occurred while starting Roblox", - Buttons = { TaskDialogButton.Close }, - Expander = new TaskDialogExpander() - { - Text = message, - CollapsedButtonText = "See details", - ExpandedButtonText = "Hide details", - Position = TaskDialogExpanderPosition.AfterText - } - }; - - errorDialog.Buttons[0].Click += (sender, e) => App.Terminate(Bootstrapper.ERROR_INSTALL_FAILURE); - - _dialogPage.Navigate(errorDialog); - _dialogPage = errorDialog; - } - } - public override void CloseBootstrapper() { if (this.InvokeRequired) diff --git a/Bloxstrap/UI/Controls.cs b/Bloxstrap/UI/Controls.cs index 7a9b8994..ad4ab765 100644 --- a/Bloxstrap/UI/Controls.cs +++ b/Bloxstrap/UI/Controls.cs @@ -1,4 +1,6 @@ -using System.Windows; +using System; +using System.Drawing; +using System.Windows; using Bloxstrap.Enums; using Bloxstrap.UI.Menu.Views; @@ -22,5 +24,13 @@ public static MessageBoxResult ShowMessageBox(string message, MessageBoxImage ic return NativeMessageBox.Show(message, icon, buttons, defaultResult); } } + + public static void ShowExceptionDialog(Exception exception) + { + Application.Current.Dispatcher.Invoke(() => + { + new ExceptionDialog(exception).ShowDialog(); + }); + } } } diff --git a/Bloxstrap/UI/ExceptionDialog.xaml b/Bloxstrap/UI/ExceptionDialog.xaml new file mode 100644 index 00000000..b047297e --- /dev/null +++ b/Bloxstrap/UI/ExceptionDialog.xaml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +