Skip to content

Commit

Permalink
Add new exception dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
pizzaboxer committed Jul 1, 2023
1 parent e708ef3 commit dc0531e
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 66 deletions.
37 changes: 22 additions & 15 deletions Bloxstrap/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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");
Expand All @@ -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)
Expand Down
18 changes: 12 additions & 6 deletions Bloxstrap/Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ namespace Bloxstrap
public class Logger
{
private readonly SemaphoreSlim _semaphore = new(1, 1);
private readonly List<string> _backlog = new();
private FileStream? _filestream;

public readonly List<string> Backlog = new();
public bool Initialized = false;
public string? Filename;

public void Initialize(string filename)
{
if (_filestream is not null)
Expand All @@ -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)
Expand All @@ -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
Expand Down
6 changes: 0 additions & 6 deletions Bloxstrap/UI/BootstrapperDialogs/BaseFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
1 change: 0 additions & 1 deletion Bloxstrap/UI/BootstrapperDialogs/IBootstrapperDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@ public interface IBootstrapperDialog
void ShowBootstrapper();
void CloseBootstrapper();
void ShowSuccess(string message, Action? callback = null);
void ShowError(string message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
2 changes: 0 additions & 2 deletions Bloxstrap/UI/BootstrapperDialogs/WinForms/DialogBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
30 changes: 0 additions & 30 deletions Bloxstrap/UI/BootstrapperDialogs/WinForms/VistaDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
12 changes: 11 additions & 1 deletion Bloxstrap/UI/Controls.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Windows;
using System;
using System.Drawing;
using System.Windows;

using Bloxstrap.Enums;
using Bloxstrap.UI.Menu.Views;
Expand All @@ -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();
});
}
}
}
49 changes: 49 additions & 0 deletions Bloxstrap/UI/ExceptionDialog.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<ui:UiWindow x:Class="Bloxstrap.UI.ExceptionDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.MessageBox"
mc:Ignorable="d"
Width="480"
MinHeight="0"
SizeToContent="Height"
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
ExtendsContentIntoTitleBar="True"
WindowStartupLocation="CenterScreen">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" x:Name="RootTitleBar" ShowMinimize="False" ShowMaximize="False" CanMaximize="False" KeyboardNavigation.TabNavigation="None" />

<Grid Grid.Row="1" Margin="16">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Width="32" Height="32" Margin="0,0,15,0" VerticalAlignment="Top" RenderOptions.BitmapScalingMode="HighQuality" Source="pack://application:,,,/Resources/MessageBox/Error.png" />
<StackPanel Grid.Column="1">
<TextBlock Text="An exception occurred while running Bloxstrap" FontSize="18" Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
<RichTextBox x:Name="ErrorRichTextBox" Padding="8" Margin="0,16,0,0" Block.LineHeight="2" FontFamily="Courier New" IsReadOnly="True" />
<TextBlock Text="Please report this exception through a GitHub issue or in our Discord chat, along with a copy of the log file that was created." Margin="0,16,0,0" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
</StackPanel>
</Grid>

<Border Grid.Row="2" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}">
<StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right">
<Button x:Name="LocateLogFileButton" Content="Locate log file" />
<ComboBox x:Name="ReportOptions" SelectedIndex="0" Padding="12,6,12,6" Margin="12,0,0,0">
<ComboBoxItem Content="Report exception" Visibility="Collapsed" />
<ComboBoxItem Content="Report via GitHub" />
<ComboBoxItem Content="Report via Discord" />
</ComboBox>
<Button x:Name="CloseButton" MinWidth="100" Content="Close" Margin="12,0,0,0" />
</StackPanel>
</Border>
</Grid>
</ui:UiWindow>
65 changes: 65 additions & 0 deletions Bloxstrap/UI/ExceptionDialog.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Media;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
using System.Windows.Media.Imaging;

using Bloxstrap.Utility;

namespace Bloxstrap.UI
{
// hmm... do i use MVVM for this?
// this is entirely static, so i think im fine without it, and this way is just so much more efficient

/// <summary>
/// Interaction logic for ExceptionDialog.xaml
/// </summary>
public partial class ExceptionDialog
{
public ExceptionDialog(Exception exception)
{
InitializeComponent();

Title = RootTitleBar.Title = $"{App.ProjectName} Exception";
ErrorRichTextBox.Selection.Text = $"{exception.GetType()}: {exception.Message}";

if (!App.Logger.Initialized)
LocateLogFileButton.Content = "Copy log contents";

LocateLogFileButton.Click += delegate
{
if (App.Logger.Initialized)
Process.Start("explorer.exe", $"/select,\"{App.Logger.Filename}\"");
else
Clipboard.SetText(String.Join("\r\n", App.Logger.Backlog));
};

ReportOptions.DropDownClosed += (sender, e) =>
{
string? selectionName = ReportOptions.SelectedItem.ToString();
ReportOptions.SelectedIndex = 0;
if (selectionName is null)
return;
if (selectionName.EndsWith("GitHub"))
Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/issues");
else if (selectionName.EndsWith("Discord"))
Utilities.ShellExecute("https://discord.gg/nKjV3mGq6R");
};

CloseButton.Click += delegate
{
Close();
};

SystemSounds.Hand.Play();
}
}
}

0 comments on commit dc0531e

Please sign in to comment.