Skip to content

Commit 4676902

Browse files
committed
show exception window in case of unhandled exceptions
1 parent 23ea1c0 commit 4676902

8 files changed

Lines changed: 169 additions & 12 deletions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
### Improvements
1515

1616
- merge game setup, game state and weather into one page
17+
- A window is now displayed on exceptions, giving you an opportunity to easily report the issue
1718

1819
### Fixes
1920

2021
- fixed saving of game settings and game setup
22+
- Minimum Sentiment Value changed from 0 to -100
2123

2224
## v0.6.0
2325

SOTFEdit/App.xaml.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
using System.Windows;
77
using System.Windows.Markup;
88
using CommunityToolkit.Mvvm.DependencyInjection;
9+
using CommunityToolkit.Mvvm.Messaging;
910
using Microsoft.Extensions.DependencyInjection;
1011
using Newtonsoft.Json;
1112
using NLog;
1213
using SOTFEdit.Model;
14+
using SOTFEdit.Model.Events;
1315
using SOTFEdit.Model.Storage;
1416
using SOTFEdit.View;
1517
using SOTFEdit.ViewModel;
@@ -111,5 +113,7 @@ private static void LogUnhandledException(Exception exception, string source)
111113
{
112114
Logger.Error(exception, message);
113115
}
116+
117+
WeakReferenceMessenger.Default.Send(new UnhandledExceptionEvent(exception));
114118
}
115119
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
3+
namespace SOTFEdit.Model.Events;
4+
5+
public class UnhandledExceptionEvent
6+
{
7+
public UnhandledExceptionEvent(Exception exception)
8+
{
9+
Exception = exception;
10+
}
11+
12+
public Exception Exception { get; }
13+
}

SOTFEdit/SOTFEdit.csproj

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
</PropertyGroup>
1212

1313
<ItemGroup>
14-
<None Remove="images\default_screenshot.png"/>
15-
<None Remove="images\kv.jpg"/>
16-
<None Remove="images\player.jpg"/>
17-
<None Remove="images\vg.jpg"/>
14+
<None Remove="images\default_screenshot.png" />
15+
<None Remove="images\kv.jpg" />
16+
<None Remove="images\player.jpg" />
17+
<None Remove="images\vg.jpg" />
1818
<None Update="data\actorTemplate.txt">
1919
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
2020
</None>
@@ -24,7 +24,7 @@
2424
</ItemGroup>
2525

2626
<ItemGroup>
27-
<Content Include="icons8-kleine-axt-doodle-96.ico"/>
27+
<Content Include="icons8-kleine-axt-doodle-96.ico" />
2828
<Content Include="images\kv.jpg">
2929
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
3030
</Content>
@@ -43,13 +43,13 @@
4343
</ItemGroup>
4444

4545
<ItemGroup>
46-
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.0.0"/>
47-
<PackageReference Include="MahApps.Metro" Version="2.4.9"/>
48-
<PackageReference Include="MahApps.Metro.IconPacks.MaterialDesign" Version="4.11.0"/>
49-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0"/>
50-
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
51-
<PackageReference Include="NLog" Version="5.1.2"/>
52-
<PackageReference Include="Semver" Version="2.3.0"/>
46+
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.0.0" />
47+
<PackageReference Include="MahApps.Metro" Version="2.4.9" />
48+
<PackageReference Include="MahApps.Metro.IconPacks.MaterialDesign" Version="4.11.0" />
49+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
50+
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
51+
<PackageReference Include="NLog" Version="5.1.2" />
52+
<PackageReference Include="Semver" Version="2.3.0" />
5353
</ItemGroup>
5454

5555
<ItemGroup>

SOTFEdit/View/MainWindow.xaml.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ private void SetupListeners()
7272
(_, message) => { OnRequestSpawnFollowerEvent(message); });
7373
WeakReferenceMessenger.Default.Register<RequestRestoreBackupsEvent>(this,
7474
(_, message) => { OnRequestRestoreBackupsEvent(message); });
75+
WeakReferenceMessenger.Default.Register<UnhandledExceptionEvent>(this,
76+
(_, message) => { OnUnhandledExceptionEvent(message); });
77+
}
78+
79+
private void OnUnhandledExceptionEvent(UnhandledExceptionEvent message)
80+
{
81+
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
82+
{
83+
var unhandledExceptionWindow = new UnhandledExceptionWindow(this, message.Exception);
84+
unhandledExceptionWindow.ShowDialog();
85+
}));
7586
}
7687

7788
private static void OnRequestRestoreBackupsEvent(RequestRestoreBackupsEvent message)
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<mah:MetroWindow x:Class="SOTFEdit.View.UnhandledExceptionWindow"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
7+
xmlns:viewModel="clr-namespace:SOTFEdit.ViewModel"
8+
d:DataContext="{d:DesignInstance viewModel:UnhandledExceptionViewModel}"
9+
mc:Ignorable="d"
10+
Padding="15"
11+
WindowStartupLocation="CenterOwner"
12+
WindowTransitionsEnabled="False"
13+
TitleCharacterCasing="Normal"
14+
Title="Unhandled Exception" Height="800" Width="800">
15+
<Window.Resources>
16+
<Style x:Key="Label"
17+
TargetType="TextBlock">
18+
<Setter Property="FontWeight" Value="Bold" />
19+
<Setter Property="Margin" Value="0,8,0,4" />
20+
</Style>
21+
<Style x:Key="Content"
22+
TargetType="TextBlock">
23+
<Setter Property="Margin" Value="0,4,0,8" />
24+
</Style>
25+
</Window.Resources>
26+
<Grid>
27+
<Grid.RowDefinitions>
28+
<!-- Info -->
29+
<RowDefinition Height="auto" />
30+
<!-- Exception details -->
31+
<RowDefinition Height="*" />
32+
<!-- Button -->
33+
<RowDefinition Height="auto" />
34+
</Grid.RowDefinitions>
35+
36+
<!-- Info -->
37+
<TextBlock Margin="16"
38+
FontSize="14"
39+
Text="An unexpected error occured. The application state might be corrupted."
40+
TextWrapping="Wrap" />
41+
42+
<!-- Exception details -->
43+
<GroupBox Grid.Row="1" Header="Exception Details" Margin="16,8,16,8">
44+
<ScrollViewer HorizontalScrollBarVisibility="Auto"
45+
VerticalScrollBarVisibility="Auto">
46+
<StackPanel>
47+
<!-- Exception Message -->
48+
<TextBlock Style="{StaticResource Label}"
49+
Text="Exception message" />
50+
<TextBlock
51+
Text="{Binding Exception.Message, Mode=OneWay, TargetNullValue=-}"
52+
TextWrapping="Wrap" />
53+
<!-- Exception Type -->
54+
<TextBlock Style="{StaticResource Label}"
55+
Text="Exception type" />
56+
<TextBlock Style="{StaticResource Content}"
57+
Text="{Binding ExceptionType, Mode=OneWay, TargetNullValue=-}" />
58+
<!-- Callstack -->
59+
<TextBlock Style="{StaticResource Label}"
60+
Text="Callstack" />
61+
<TextBlock Style="{StaticResource Content}"
62+
Text="{Binding Exception.StackTrace, Mode=OneWay, TargetNullValue=-}" />
63+
<!-- Inner exception -->
64+
<TextBlock Style="{StaticResource Label}"
65+
Text="Inner exception" />
66+
<TextBlock Style="{StaticResource Content}"
67+
Text="{Binding Exception.InnerException, Mode=OneWay, TargetNullValue=-}" />
68+
</StackPanel>
69+
</ScrollViewer>
70+
</GroupBox>
71+
<StackPanel Orientation="Horizontal" Grid.Row="2" HorizontalAlignment="Right" Margin="15">
72+
<Button Background="DarkGreen" Padding="10" Margin="0 0 10 0" Command="{Binding CopyToClipboardCommand}">Copy Error to Clipboard</Button>
73+
<Button Background="DarkRed" Padding="10" Command="{Binding ExitApplicationCommand}">Exit Application</Button>
74+
</StackPanel>
75+
</Grid>
76+
</mah:MetroWindow>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
using System.Windows;
3+
using SOTFEdit.ViewModel;
4+
5+
namespace SOTFEdit.View;
6+
7+
public partial class UnhandledExceptionWindow
8+
{
9+
public UnhandledExceptionWindow(Window owner, Exception exception)
10+
{
11+
Owner = owner;
12+
DataContext = new UnhandledExceptionViewModel(exception);
13+
InitializeComponent();
14+
}
15+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Text;
3+
using System.Windows;
4+
using CommunityToolkit.Mvvm.ComponentModel;
5+
using CommunityToolkit.Mvvm.Input;
6+
7+
namespace SOTFEdit.ViewModel;
8+
9+
// ReSharper disable once ClassNeverInstantiated.Global
10+
public partial class UnhandledExceptionViewModel : ObservableObject
11+
{
12+
public UnhandledExceptionViewModel(Exception exception)
13+
{
14+
Exception = exception;
15+
}
16+
17+
public Exception Exception { get; }
18+
public string? ExceptionType => Exception.GetType().FullName;
19+
20+
[RelayCommand]
21+
private void CopyToClipboard()
22+
{
23+
var text = new StringBuilder();
24+
text.AppendLine($"Message: {Exception.Message}");
25+
text.AppendLine($"Exception Type: {ExceptionType}");
26+
text.AppendLine($"Callstack: {Exception.StackTrace}");
27+
text.AppendLine($"Inner Exception: {Exception.InnerException}");
28+
Clipboard.SetText(text.ToString());
29+
}
30+
31+
[RelayCommand]
32+
private static void ExitApplication()
33+
{
34+
Environment.Exit(-1);
35+
}
36+
}

0 commit comments

Comments
 (0)