Skip to content

Commit

Permalink
Added global exception handling to TestApp
Browse files Browse the repository at this point in the history
  • Loading branch information
RolandKoenig committed Mar 24, 2024
1 parent e316999 commit 212372d
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 3 deletions.
6 changes: 6 additions & 0 deletions RolandK.AvaloniaExtensions.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RolandK.AvaloniaExtensions.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RolandK.AvaloniaExtensions.ExceptionHandling", "src\RolandK.AvaloniaExtensions.ExceptionHandling\RolandK.AvaloniaExtensions.ExceptionHandling.csproj", "{FC6CF99C-571A-454F-B385-52F0DEC21BFA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RolandK.AvaloniaExtensions.TestApp.ExceptionViewer", "src\RolandK.AvaloniaExtensions.TestApp.ExceptionViewer\RolandK.AvaloniaExtensions.TestApp.ExceptionViewer.csproj", "{ED908FBE-7113-4E38-A725-89AA6B4BA9C2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -45,6 +47,10 @@ Global
{FC6CF99C-571A-454F-B385-52F0DEC21BFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC6CF99C-571A-454F-B385-52F0DEC21BFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC6CF99C-571A-454F-B385-52F0DEC21BFA}.Release|Any CPU.Build.0 = Release|Any CPU
{ED908FBE-7113-4E38-A725-89AA6B4BA9C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED908FBE-7113-4E38-A725-89AA6B4BA9C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED908FBE-7113-4E38-A725-89AA6B4BA9C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED908FBE-7113-4E38-A725-89AA6B4BA9C2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@ public static async Task ShowGlobalExceptionDialogAsync(
/// <summary>
/// Tries to show an error dialog with some exception details.
/// If it is not possible for any reason, this method simply does nothing.
///
/// This call is a blocking call. It es meant to be called within a global
/// try-catch block in Program.cs
/// </summary>
/// <param name="exception">The exception to be shown to the user.</param>
/// <param name="applicationTempDirectoryName">This should be a technical name, the method uses it to create a temporary directory in the filesystem.</param>
/// <param name="exceptionViewerExecutableProjectName">The project name of the executable showing the error dialog.</param>
/// <param name="exceptionAnalyzers">If null, a default collection of IExceptionAnalyzers ist used.</param>
public static void TryShowGlobalExceptionDialogInAnotherProcess(
public static void TryShowBlockingGlobalExceptionDialogInAnotherProcess(
Exception exception,
string applicationTempDirectoryName,
string exceptionViewerExecutableProjectName,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="RolandK.AvaloniaExtensions.TestApp.ExceptionViewer.App"
RequestedThemeVariant="Default">
<Application.Styles>
<FluentTheme />
</Application.Styles>
</Application>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Avalonia.Markup.Xaml;
using RolandK.AvaloniaExtensions.ExceptionHandling;

namespace RolandK.AvaloniaExtensions.TestApp.ExceptionViewer;

public partial class App : ExceptionViewerApplication
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
}
21 changes: 21 additions & 0 deletions src/RolandK.AvaloniaExtensions.TestApp.ExceptionViewer/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Avalonia;
using System;

namespace RolandK.AvaloniaExtensions.TestApp.ExceptionViewer;

internal class Program
{
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);

// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.WithInterFont()
.LogToTrace();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<TrimMode>copyused</TrimMode>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Avalonia" Version="11.0.10" />
<PackageReference Include="Avalonia.Desktop" Version="11.0.10" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.10" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.10" />
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.10" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\RolandK.AvaloniaExtensions.ExceptionHandling\RolandK.AvaloniaExtensions.ExceptionHandling.csproj" />
</ItemGroup>
</Project>
8 changes: 8 additions & 0 deletions src/RolandK.AvaloniaExtensions.TestApp/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@
Command="{Binding Path=RecreateTestDataCommand}"/>
<MenuItem Header="Show dummy MessageBox"
Command="{Binding Path=ShowDummyMessageBoxCommand}" />

<Separator />
<MenuItem Header="Show dummy exception (this process)"
Click="OnMnu_ShowDummyException_ThisProcess_Click" />
<MenuItem Header="Show dummy exception (other process)"
Click="OnMnu_ShowDummyException_OtherProcess_Click" />
<MenuItem Header="Simulate unhandled exception"
Click="OnMnu_SimulateUnhandledException_Click" />
</MenuItem>
</Menu>

Expand Down
35 changes: 35 additions & 0 deletions src/RolandK.AvaloniaExtensions.TestApp/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using System;
using Avalonia.Interactivity;
using RolandK.AvaloniaExtensions.ExceptionHandling;
using RolandK.AvaloniaExtensions.Mvvm.Controls;

namespace RolandK.AvaloniaExtensions.TestApp;
Expand All @@ -8,4 +11,36 @@ public MainWindow()
{
this.InitializeComponent();
}

private async void OnMnu_ShowDummyException_ThisProcess_Click(object? sender, RoutedEventArgs e)
{
try
{
throw new InvalidOperationException("Dummy exception");
}
catch (Exception ex)
{
await GlobalErrorReporting.ShowGlobalExceptionDialogAsync(ex, this);
}
}

private void OnMnu_ShowDummyException_OtherProcess_Click(object? sender, RoutedEventArgs e)
{
try
{
throw new InvalidOperationException("Dummy exception");
}
catch (Exception ex)
{
GlobalErrorReporting.TryShowBlockingGlobalExceptionDialogInAnotherProcess(
ex,
".RKAvaloniaExtensions.TestApp",
"RolandK.AvaloniaExtensions.TestApp.ExceptionViewer");
}
}

private void OnMnu_SimulateUnhandledException_Click(object? sender, RoutedEventArgs e)
{
throw new InvalidOperationException("Dummy exception");
}
}
18 changes: 16 additions & 2 deletions src/RolandK.AvaloniaExtensions.TestApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Avalonia;
using Microsoft.Extensions.DependencyInjection;
using RolandK.AvaloniaExtensions.DependencyInjection;
using RolandK.AvaloniaExtensions.ExceptionHandling;
using RolandK.AvaloniaExtensions.TestApp.Services;

namespace RolandK.AvaloniaExtensions.TestApp;
Expand All @@ -12,8 +13,21 @@ public static class Program
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
public static void Main(string[] args)
{
try
{
BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
}
catch (Exception ex)
{
GlobalErrorReporting.TryShowBlockingGlobalExceptionDialogInAnotherProcess(
ex,
".RKAvaloniaExtensions.TestApp",
"RolandK.AvaloniaExtensions.TestApp.ExceptionViewer");
}
}

// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

<ItemGroup>
<ProjectReference Include="..\RolandK.AvaloniaExtensions.DependencyInjection\RolandK.AvaloniaExtensions.DependencyInjection.csproj" />
<ProjectReference Include="..\RolandK.AvaloniaExtensions.ExceptionHandling\RolandK.AvaloniaExtensions.ExceptionHandling.csproj" />
<ProjectReference Include="..\RolandK.AvaloniaExtensions.TestApp.ExceptionViewer\RolandK.AvaloniaExtensions.TestApp.ExceptionViewer.csproj" />
<ProjectReference Include="..\RolandK.AvaloniaExtensions\RolandK.AvaloniaExtensions.csproj" />
</ItemGroup>

Expand Down

0 comments on commit 212372d

Please sign in to comment.