Skip to content

Commit be217e6

Browse files
committed
修复错误收集对话框在多错误抛出时的问题
1 parent f818c7a commit be217e6

File tree

8 files changed

+173
-131
lines changed

8 files changed

+173
-131
lines changed

Natsurainko.FluentLauncher/App.xaml.cs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using FluentLauncher.Infra.UI.Windows;
1+
using CommunityToolkit.Mvvm.Messaging;
2+
using FluentLauncher.Infra.UI.Windows;
23
using Microsoft.Extensions.DependencyInjection;
34
using Microsoft.Extensions.Logging;
45
using Microsoft.UI.Dispatching;
@@ -149,6 +150,8 @@ partial class App
149150
/// </summary>
150151
partial class App
151152
{
153+
private static bool _exceptionDialogShowing = false;
154+
152155
/// <summary>
153156
/// Configure the exception handling for the application.
154157
/// </summary>
@@ -216,7 +219,15 @@ static void ShowExceptionWithContentDialog(Exception exception)
216219
{
217220
try
218221
{
219-
await new ExceptionDialog(GetErrorMessage(exception)).ShowAsync();
222+
if (_exceptionDialogShowing)
223+
{
224+
WeakReferenceMessenger.Default.Send(new ExceptionDialogRepeatedlyRequestMessage(exception));
225+
return;
226+
}
227+
228+
_exceptionDialogShowing = true;
229+
await new ExceptionDialog(exception).ShowAsync();
230+
_exceptionDialogShowing = false;
220231
}
221232
catch (Exception ex)
222233
{
@@ -232,7 +243,7 @@ static void ShowExceptionWithContentDialog(Exception exception)
232243
/// <param name="e"></param>
233244
/// <param name="callCount"></param>
234245
/// <returns></returns>
235-
static string GetErrorMessage(Exception e, int callCount = 0)
246+
public static string GetErrorMessage(Exception e, int callCount = 0)
236247
{
237248
if (e is null) return string.Empty;
238249
if (callCount > 5) // Prevent infinite recursion
@@ -250,17 +261,17 @@ static string GetErrorMessage(Exception e, int callCount = 0)
250261
}
251262
else
252263
{
253-
sb.AppendLine($"{indent}Message: {e.Message}");
254-
sb.AppendLine($"{indent}Source: {e.Source}");
255-
sb.AppendLine($"{indent}TargetSite: {e.TargetSite}");
256-
sb.AppendLine($"{indent}StackTrace: {e.StackTrace}");
264+
if (!string.IsNullOrEmpty(e.Message)) sb.AppendLine($"{indent}Message: {e.Message.TrimEnd()}");
265+
if (!string.IsNullOrEmpty(e.Source)) sb.AppendLine($"{indent}Source: {e.Source}");
266+
if (!string.IsNullOrEmpty(e.TargetSite?.ToString())) sb.AppendLine($"{indent}TargetSite: {e.TargetSite}");
267+
if (!string.IsNullOrEmpty(e.StackTrace?.ToString())) sb.AppendLine($"{indent}StackTrace: {e.StackTrace}");
257268

258269
if (e.Data != null && e.Data.Count > 0)
259270
{
260271
sb.AppendLine($"{indent}Data:");
261272

262273
foreach (var key in e.Data.Keys)
263-
sb.AppendLine($"{indent} {key}: {e.Data[key]}");
274+
if (!string.IsNullOrEmpty(e.Data[key]?.ToString())) sb.AppendLine($"{indent} {key}: {e.Data[key]!.ToString()!.TrimEnd()}");
264275
}
265276

266277
if (e.InnerException != null)

Natsurainko.FluentLauncher/Services/UI/Messaging/Messages.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Natsurainko.FluentLauncher.Models.UI;
44
using Natsurainko.FluentLauncher.ViewModels;
55
using Nrk.FluentCore.Authentication;
6+
using System;
67
using System.Collections.Generic;
78

89
namespace Natsurainko.FluentLauncher.Services.UI.Messaging;
@@ -35,4 +36,6 @@ class DownloadTaskCreatedMessage(int eventId) : ValueChangedMessage<int>(eventId
3536
class GlobalNavigationMessage(string pageKey, object? parameter = null) : ValueChangedMessage<string>(pageKey)
3637
{
3738
public object? Parameter { get; init; } = parameter;
38-
}
39+
}
40+
41+
class ExceptionDialogRepeatedlyRequestMessage(Exception exception) : ValueChangedMessage<Exception>(exception);

Natsurainko.FluentLauncher/ViewModels/Dialogs/ExceptionDialogViewModel.cs

Lines changed: 0 additions & 21 deletions
This file was deleted.

Natsurainko.FluentLauncher/Views/Dialogs/ExceptionDialog.xaml

Lines changed: 98 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,115 @@
22
x:Class="Natsurainko.FluentLauncher.Views.Dialogs.ExceptionDialog"
33
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
44
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
56
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6-
xmlns:local="using:Natsurainko.FluentLauncher.Views.Dialogs"
77
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8-
xmlns:vm="using:Natsurainko.FluentLauncher.ViewModels.Dialogs"
9-
x:Name="Dialog"
10-
x:Uid="Dialogs_ExceptionDialog"
11-
Title="The program has encountered an error"
12-
d:DataContext="{d:DesignInstance Type=vm:ExceptionDialogViewModel}"
13-
DefaultButton="Primary"
14-
PrimaryButtonCommand="{x:Bind VM.CopyAndLaunchGitHubCommand}"
15-
PrimaryButtonText="Copy and go to GitHub"
16-
SecondaryButtonText="Close"
178
Style="{ThemeResource DefaultContentDialogStyle}"
9+
Unloaded="Dialog_Unloaded"
1810
mc:Ignorable="d">
1911

12+
<ContentDialog.Resources>
13+
<Thickness x:Key="ContentDialogPadding">0</Thickness>
14+
</ContentDialog.Resources>
15+
<ContentDialog.Title>
16+
<StackPanel Margin="24,24,24,0">
17+
<TextBlock x:Uid="Dialogs_ExceptionDialog_Title" Text="The program has encountered an error" />
18+
</StackPanel>
19+
</ContentDialog.Title>
20+
2021
<Grid>
22+
<Grid.Resources>
23+
<ResourceDictionary>
24+
<ResourceDictionary.ThemeDictionaries>
25+
<ResourceDictionary x:Key="Light">
26+
<StaticResource x:Key="ContentDialogBorderBrush" ResourceKey="ContentDialogDimmingThemeBrush" />
27+
</ResourceDictionary>
28+
<ResourceDictionary x:Key="Dark">
29+
<StaticResource x:Key="ContentDialogBorderBrush" ResourceKey="ContentDialogSeparatorBorderBrush" />
30+
</ResourceDictionary>
31+
</ResourceDictionary.ThemeDictionaries>
32+
</ResourceDictionary>
33+
</Grid.Resources>
2134
<Grid.RowDefinitions>
35+
<RowDefinition Height="1*" />
2236
<RowDefinition Height="Auto" />
23-
<RowDefinition />
2437
</Grid.RowDefinitions>
25-
<StackPanel Grid.Row="0">
26-
<TextBlock Text="Please report this issue on GitHub." />
27-
<TextBlock Text="Providing the following information might help us fix the issue:" />
28-
</StackPanel>
38+
<Grid
39+
Height="Auto"
40+
Padding="24,0,24,20"
41+
Background="Transparent">
42+
<Grid>
43+
<Grid.RowDefinitions>
44+
<RowDefinition Height="Auto" />
45+
<RowDefinition Height="Auto" />
46+
<RowDefinition Height="*" />
47+
</Grid.RowDefinitions>
48+
<StackPanel Grid.Row="0">
49+
<TextBlock x:Uid="Dialogs_ExceptionDialog_Description_1" Text="Please report this issue on GitHub." />
50+
<TextBlock x:Uid="Dialogs_ExceptionDialog_Description_2" Text="Providing the following information might help us fix the issue:" />
51+
</StackPanel>
52+
53+
<ScrollViewer
54+
Grid.Row="1"
55+
Padding="0,16"
56+
HorizontalScrollBarVisibility="Auto"
57+
VerticalScrollMode="Disabled">
58+
<controls:Segmented x:Name="Segmented" SelectionChanged="Segmented_SelectionChanged" />
59+
</ScrollViewer>
2960

30-
<ScrollViewer
61+
<ScrollViewer
62+
Grid.Row="2"
63+
Background="{ThemeResource ControlAltFillColorSecondaryBrush}"
64+
BorderBrush="{ThemeResource ControlStrokeColorDefaultBrush}"
65+
BorderThickness="1"
66+
CornerRadius="4"
67+
HorizontalScrollBarVisibility="Auto">
68+
<TextBlock
69+
x:Name="TextBlock"
70+
Margin="8"
71+
IsTextSelectionEnabled="True" />
72+
</ScrollViewer>
73+
</Grid>
74+
75+
</Grid>
76+
<Rectangle
3177
Grid.Row="1"
32-
Margin="0,4,0,0"
33-
Padding="0,0,10,10"
34-
BorderBrush="Black"
35-
BorderThickness="1"
36-
CornerRadius="5"
37-
HorizontalScrollBarVisibility="Auto">
38-
<Grid Margin="10,5,0,0">
39-
<TextBlock IsTextSelectionEnabled="True" Text="{x:Bind VM.ErrorMessage}" />
78+
HorizontalAlignment="Stretch"
79+
VerticalAlignment="Stretch"
80+
Fill="{ThemeResource ContentDialogSmokeFill}" />
81+
<Border
82+
Grid.Row="1"
83+
Padding="24"
84+
HorizontalAlignment="Stretch"
85+
VerticalAlignment="Bottom"
86+
Background="{ThemeResource ContentDialogBackground}"
87+
BorderBrush="{ThemeResource ContentDialogBorderBrush}"
88+
BorderThickness="0,1,0,0">
89+
<Grid x:Name="CommandSpace" XYFocusKeyboardNavigation="Enabled">
90+
<Grid.ColumnDefinitions>
91+
<ColumnDefinition Width="*" />
92+
<ColumnDefinition Width="{ThemeResource ContentDialogButtonSpacing}" />
93+
<ColumnDefinition Width="*" />
94+
</Grid.ColumnDefinitions>
95+
<Button
96+
Grid.Column="0"
97+
HorizontalAlignment="Stretch"
98+
Click="CopyButton_Click"
99+
ElementSoundMode="FocusOnly"
100+
IsTabStop="False"
101+
Style="{ThemeResource AccentButtonStyle}">
102+
<TextBlock x:Uid="Dialogs_ExceptionDialog_B1" Text="Copy and go to GitHub" />
103+
</Button>
104+
<Button
105+
Grid.Column="2"
106+
HorizontalAlignment="Stretch"
107+
Click="CloseButton_Click"
108+
ElementSoundMode="FocusOnly"
109+
IsTabStop="False">
110+
<TextBlock x:Uid="Dialogs_ExceptionDialog_B2" Text="Close" />
111+
</Button>
40112
</Grid>
41-
</ScrollViewer>
113+
</Border>
42114
</Grid>
115+
43116
</ContentDialog>
Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,62 @@
1+
using CommunityToolkit.Mvvm.Messaging;
2+
using CommunityToolkit.WinUI.Controls;
3+
using Microsoft.UI.Xaml;
14
using Microsoft.UI.Xaml.Controls;
2-
using Natsurainko.FluentLauncher.ViewModels.Dialogs;
5+
using Natsurainko.FluentLauncher.Services.UI.Messaging;
6+
using Natsurainko.FluentLauncher.Utils;
7+
using System;
8+
using System.Linq;
9+
using Windows.System;
310

411
namespace Natsurainko.FluentLauncher.Views.Dialogs;
512

613
// This dialog is not managed by the DI framework because it is called in App.xaml.cs, where a scope is not available
7-
public sealed partial class ExceptionDialog : ContentDialog
14+
public sealed partial class ExceptionDialog : ContentDialog, IRecipient<ExceptionDialogRepeatedlyRequestMessage>
815
{
9-
ExceptionDialogViewModel VM => (ExceptionDialogViewModel)DataContext;
10-
11-
public ExceptionDialog(string errorMessage = "")
16+
public ExceptionDialog(Exception exception)
1217
{
1318
InitializeComponent();
1419

1520
XamlRoot = MainWindow.XamlRoot;
16-
RequestedTheme = App.MainWindow.ContentFrame.RequestedTheme;
17-
DataContext = new ExceptionDialogViewModel(errorMessage);
21+
RequestedTheme = (App.MainWindow.Content as FrameworkElement)!.RequestedTheme;
22+
23+
Segmented.Items.Add(new SegmentedItem
24+
{
25+
Content = exception.GetType().Name,
26+
IsSelected = true,
27+
Tag = exception
28+
});
29+
30+
WeakReferenceMessenger.Default.Register(this);
31+
}
32+
33+
private void Dialog_Unloaded(object sender, RoutedEventArgs e) => WeakReferenceMessenger.Default.UnregisterAll(this);
34+
35+
void IRecipient<ExceptionDialogRepeatedlyRequestMessage>.Receive(ExceptionDialogRepeatedlyRequestMessage message)
36+
{
37+
App.DispatcherQueue.TryEnqueue(() =>
38+
{
39+
Segmented.Items.Add(new SegmentedItem
40+
{
41+
Content = message.Value.GetType().Name,
42+
Tag = message.Value
43+
});
44+
});
1845
}
19-
}
46+
private void Segmented_SelectionChanged(object sender, SelectionChangedEventArgs e)
47+
{
48+
TextBlock.Text = App.GetErrorMessage((Exception)((SegmentedItem)Segmented.SelectedItem).Tag!);
49+
}
50+
51+
private async void CopyButton_Click(object sender, RoutedEventArgs e)
52+
{
53+
string[] exceptions = [.. Segmented.Items.OfType<SegmentedItem>()
54+
.Select(s => s.Tag as Exception)
55+
.Select(e => App.GetErrorMessage(e!))];
56+
57+
ClipboardHepler.SetText(string.Join("\r\n", exceptions));
58+
await Launcher.LaunchUriAsync(new Uri("https://github.com/Xcube-Studio/Natsurainko.FluentLauncher/issues/new/choose"));
59+
}
60+
61+
private void CloseButton_Click(object sender, RoutedEventArgs e) => this.Hide();
62+
}

Natsurainko.FluentLauncher/Views/ExceptionPage.xaml

Lines changed: 0 additions & 52 deletions
This file was deleted.

Natsurainko.FluentLauncher/Views/ExceptionPage.xaml.cs

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)