From 3827c189c49f748c442325996e9128b62cdbb7fb Mon Sep 17 00:00:00 2001 From: Ionite Date: Fri, 19 Jan 2024 15:28:04 -0500 Subject: [PATCH 1/3] Add CopyDetails resource --- StabilityMatrix.Avalonia/Languages/Resources.Designer.cs | 9 +++++++++ StabilityMatrix.Avalonia/Languages/Resources.resx | 3 +++ 2 files changed, 12 insertions(+) diff --git a/StabilityMatrix.Avalonia/Languages/Resources.Designer.cs b/StabilityMatrix.Avalonia/Languages/Resources.Designer.cs index 48cea020..daf138be 100644 --- a/StabilityMatrix.Avalonia/Languages/Resources.Designer.cs +++ b/StabilityMatrix.Avalonia/Languages/Resources.Designer.cs @@ -167,6 +167,15 @@ namespace StabilityMatrix.Avalonia.Languages { } } + /// + /// Looks up a localized string similar to Copy Details. + /// + public static string Action_CopyDetails { + get { + return ResourceManager.GetString("Action_CopyDetails", resourceCulture); + } + } + /// /// Looks up a localized string similar to Copy Trigger Words. /// diff --git a/StabilityMatrix.Avalonia/Languages/Resources.resx b/StabilityMatrix.Avalonia/Languages/Resources.resx index 9a64e94f..cef29119 100644 --- a/StabilityMatrix.Avalonia/Languages/Resources.resx +++ b/StabilityMatrix.Avalonia/Languages/Resources.resx @@ -936,4 +936,7 @@ No extensions found. + + Copy Details + From 47736c828cd2ba222d12292f4346b2a11871df50 Mon Sep 17 00:00:00 2001 From: Ionite Date: Fri, 19 Jan 2024 15:28:15 -0500 Subject: [PATCH 2/3] Add copy button for exception dialog --- StabilityMatrix.Avalonia/Program.cs | 9 +++- .../ViewModels/Dialogs/ExceptionViewModel.cs | 35 ++++++++++++++++ .../Views/Dialogs/ExceptionDialog.axaml | 41 +++++++++++++++---- .../Views/Dialogs/ExceptionDialog.axaml.cs | 12 ++++++ 4 files changed, 86 insertions(+), 11 deletions(-) diff --git a/StabilityMatrix.Avalonia/Program.cs b/StabilityMatrix.Avalonia/Program.cs index 40d8531c..8e60cfe7 100644 --- a/StabilityMatrix.Avalonia/Program.cs +++ b/StabilityMatrix.Avalonia/Program.cs @@ -347,11 +347,13 @@ public static class Program if (e.ExceptionObject is not Exception ex) return; + SentryId? sentryId = null; + // Exception automatically logged by Sentry if enabled if (SentrySdk.IsEnabled) { ex.SetSentryMechanism("AppDomain.UnhandledException", handled: false); - SentrySdk.CaptureException(ex); + sentryId = SentrySdk.CaptureException(ex); SentrySdk.FlushAsync().SafeFireAndForget(); } else @@ -361,7 +363,10 @@ public static class Program if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime lifetime) { - var dialog = new ExceptionDialog { DataContext = new ExceptionViewModel { Exception = ex } }; + var dialog = new ExceptionDialog + { + DataContext = new ExceptionViewModel { Exception = ex, SentryId = sentryId } + }; var mainWindow = lifetime.MainWindow; // We can only show dialog if main window exists, and is visible diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/ExceptionViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/ExceptionViewModel.cs index 42e8a6d6..9531c864 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/ExceptionViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/ExceptionViewModel.cs @@ -1,4 +1,5 @@ using System; +using Sentry; using StabilityMatrix.Avalonia.ViewModels.Base; using StabilityMatrix.Avalonia.Views.Dialogs; using StabilityMatrix.Core.Attributes; @@ -12,7 +13,41 @@ public partial class ExceptionViewModel : ViewModelBase { public Exception? Exception { get; set; } + public SentryId? SentryId { get; set; } + public string? Message => Exception?.Message; public string? ExceptionType => Exception?.GetType().Name ?? ""; + + public string? FormatAsMarkdown() + { + if (Exception is null) + { + return null; + } + + var message = $"## Exception\n{ExceptionType}: {Message}\n"; + + if (SentryId is not null) + { + message += $"### Sentry ID\n```\n{SentryId}\n```\n"; + } + + if (Exception.StackTrace != null) + { + message += $"### Stack Trace\n```\n{Exception.StackTrace}\n```\n"; + } + + if (Exception.InnerException is { } innerException) + { + message += $"## Inner Exception\n{innerException.GetType().Name}: {innerException.Message}\n"; + + if (innerException.StackTrace != null) + { + message += $"### Stack Trace\n```\n{innerException.StackTrace}\n```\n"; + } + } + + return message; + } } diff --git a/StabilityMatrix.Avalonia/Views/Dialogs/ExceptionDialog.axaml b/StabilityMatrix.Avalonia/Views/Dialogs/ExceptionDialog.axaml index 2612d4db..89bf3c97 100644 --- a/StabilityMatrix.Avalonia/Views/Dialogs/ExceptionDialog.axaml +++ b/StabilityMatrix.Avalonia/Views/Dialogs/ExceptionDialog.axaml @@ -6,6 +6,7 @@ xmlns:mocks="clr-namespace:StabilityMatrix.Avalonia.DesignData" xmlns:controls="clr-namespace:StabilityMatrix.Avalonia.Controls" xmlns:lang="clr-namespace:StabilityMatrix.Avalonia.Languages" + xmlns:fluentIcons="clr-namespace:FluentIcons.Avalonia.Fluent;assembly=FluentIcons.Avalonia.Fluent" d:DataContext="{x:Static mocks:DesignData.ExceptionViewModel}" x:DataType="dialogs:ExceptionViewModel" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="550" @@ -73,16 +74,38 @@ - - + + +