Browse Source

Added lots of new report state info

CPKreuz 1 year ago
parent
commit
653c0a9351

+ 1 - 1
src/PixiEditor.Extensions/Common/Localization/LocalizedString.cs

@@ -26,7 +26,7 @@ public struct LocalizedString
     }
     public string Value { get; private set; }
 
-    public object[] Parameters { get; set; }
+    public object[]? Parameters { get; set; }
 
     public LocalizedString(string key)
     {

+ 1 - 1
src/PixiEditor.Extensions/Common/UserPreferences/IPreferences.cs

@@ -2,7 +2,7 @@
 
 public interface IPreferences
 {
-    public static IPreferences Current { get; private set; }
+    public static IPreferences? Current { get; private set; }
 
     /// <summary>
     /// Saves the preferences to be stored permanently.

+ 1 - 1
src/PixiEditor/Models/Commands/CommandLog/CommandLog.cs

@@ -35,7 +35,7 @@ internal class CommandLog
             var relativeSpan = entry.DateTime - relativeTime;
             string canExecute = entry.CanExecute.HasValue ? entry.CanExecute.ToString() : "not executed";
             
-            builder.AppendLine($"{entry.Command.InternalName} | CanExecute: {canExecute} | {entry.DateTime.ToString("O", CultureInfo.InvariantCulture)} | {relativeSpan.ToString("G", CultureInfo.InvariantCulture)}");
+            builder.AppendLine($"{entry.Command.InternalName} | CanExecute: {canExecute} | {relativeSpan.TotalSeconds.ToString("F3", CultureInfo.InvariantCulture)}s ago | {entry.DateTime.ToString("O", CultureInfo.InvariantCulture)}");
         }
 
         return builder.ToString();

+ 116 - 25
src/PixiEditor/Models/DataHolders/CrashReport.cs

@@ -4,12 +4,16 @@ using System.IO;
 using System.IO.Compression;
 using System.Reflection;
 using System.Text;
+using System.Windows.Input;
 using Newtonsoft.Json;
+using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.Common.UserPreferences;
 using PixiEditor.Helpers;
 using PixiEditor.Models.Commands;
+using PixiEditor.Models.Enums;
 using PixiEditor.Parser;
 using PixiEditor.ViewModels.SubViewModels.Document;
+using PixiEditor.Views;
 
 namespace PixiEditor.Models.DataHolders;
 
@@ -23,14 +27,59 @@ internal class CrashReport : IDisposable
 
         builder
             .AppendLine($"PixiEditor {VersionHelpers.GetCurrentAssemblyVersionString(moreSpecific: true)} x{IntPtr.Size * 8} crashed on {currentTime:yyyy.MM.dd} at {currentTime:HH:mm:ss} {currentTime:zzz}")
+            .AppendLine($"Application started {GetFormatted(() => Process.GetCurrentProcess().StartTime, "yyyy.MM.dd HH:hh:ss")}, {GetFormatted(() => DateTime.Now - Process.GetCurrentProcess().StartTime, @"d\ hh\:mm\.ss")} ago")
             .AppendLine($"Report: {Guid.NewGuid()}\n")
             .AppendLine("-----System Information----")
             .AppendLine("General:")
             .AppendLine($"  OS: {Environment.OSVersion.VersionString}")
+            .AppendLine($"  Has Stylus Tablet Device: {GetFormatted(() => HasTabletDevice(TabletDeviceType.Stylus))}")
+            .AppendLine($"  Has Touch Tablet Device: {GetFormatted(() => HasTabletDevice(TabletDeviceType.Touch))}")
             .AppendLine();
 
         CrashHelper helper = new();
 
+        AppendHardwareInfo(helper, builder);
+
+        builder.AppendLine("\n--------Command Log--------\n");
+
+        try
+        {
+            builder.Append(CommandController.Current.Log.GetSummary(currentTime.LocalDateTime));
+        }
+        catch (Exception cemLogException)
+        {
+            builder.AppendLine($"Error ({cemLogException.GetType().FullName}: {cemLogException.Message}) while gathering command log, skipping...");
+        }
+        
+        builder.AppendLine("\n-----------State-----------");
+
+        try
+        {
+            AppendStateInfo(builder);
+        }
+        catch (Exception stateException)
+        {
+            builder.AppendLine($"Error ({stateException.GetType().FullName}: {stateException.Message}) while gathering state (Must be bug in GetPreferenceFormatted, GetFormatted or StringBuilder.AppendLine as these should not throw), skipping...");
+        }
+        
+        CrashHelper.AddExceptionMessage(builder, exception);
+
+        string filename = $"crash-{currentTime:yyyy-MM-dd_HH-mm-ss_fff}.zip";
+        string path = Path.Combine(
+            Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+            "PixiEditor",
+            "crash_logs");
+        Directory.CreateDirectory(path);
+
+        CrashReport report = new();
+        report.FilePath = Path.Combine(path, filename);
+        report.ReportText = builder.ToString();
+
+        return report;
+    }
+
+    private static void AppendHardwareInfo(CrashHelper helper, StringBuilder builder)
+    {
         try
         {
             helper.GetCPUInformation(builder);
@@ -57,46 +106,88 @@ internal class CrashReport : IDisposable
         {
             builder.AppendLine($"Error ({memE.GetType().FullName}: {memE.Message}) while gathering memory information, skipping...");
         }
+    }
 
-        builder.AppendLine("\n--------Command Log--------\n");
+    private static void AppendStateInfo(StringBuilder builder)
+    {
+        builder
+            .AppendLine("Culture:")
+            .AppendLine($"  Selected language: {GetPreferenceFormatted("LanguageCode", true, "system")}")
+            .AppendLine($"  Current Culture: {GetFormatted(() => CultureInfo.CurrentCulture)}")
+            .AppendLine($"  Current UI Culture: {GetFormatted(() => CultureInfo.CurrentUICulture)}")
+            .AppendLine("\nPreferences:")
+            .AppendLine($"  Has shared toolbar enabled: {GetPreferenceFormatted("EnableSharedToolbar", true, false)}")
+            .AppendLine($"  Right click mode: {GetPreferenceFormatted<RightClickMode>("RightClickMode", true)}")
+            .AppendLine($"  Has Rich presence enabled: {GetPreferenceFormatted("EnableRichPresence", true, true)}")
+            .AppendLine($"  Autosaving Enabled: {GetPreferenceFormatted(PreferencesConstants.AutosavePeriodMinutes, true, PreferencesConstants.AutosavePeriodDefault)}")
+            .AppendLine($"  Debug Mode enabled: {GetPreferenceFormatted("IsDebugModeEnabled", true, false)}")
+            .AppendLine("\nUI:")
+            .AppendLine($"  MainWindow not null: {GetFormatted(() => MainWindow.Current != null)}")
+            .AppendLine($"  MainWindow Size: {GetFormatted(() => MainWindow.Current.RenderSize)}")
+            .AppendLine($"  MainWindow State: {GetFormatted(() => MainWindow.Current.WindowState)}")
+            .AppendLine("\nViewModels:")
+            .AppendLine($"  Current Document not null: {GetFormatted(() => ViewModelMain.Current?.DocumentManagerSubViewModel?.ActiveDocument != null)}")
+            .AppendLine($"  Has active updateable change: {GetFormatted(() => ViewModelMain.Current?.DocumentManagerSubViewModel?.ActiveDocument?.UpdateableChangeActive)}")
+            .AppendLine($"  Autosave State: {GetFormatted(() => ViewModelMain.Current?.DocumentManagerSubViewModel?.ActiveDocument?.AutosaveViewModel?.MainMenuText)}")
+            .AppendLine($"  Current Tool: {GetFormatted(() => ViewModelMain.Current?.ToolsSubViewModel?.ActiveTool?.ToolName)}")
+            .AppendLine($"  Primary Color: {GetFormatted(() => ViewModelMain.Current?.ColorsSubViewModel?.PrimaryColor)}")
+            .AppendLine($"  Secondary Color: {GetFormatted(() => ViewModelMain.Current?.ColorsSubViewModel?.SecondaryColor)}");
+    }
 
+    private static bool HasTabletDevice(TabletDeviceType type) => Tablet.TabletDevices.Cast<TabletDevice>().Any(tabletDevice => tabletDevice.Type == type);
+
+    private static string GetPreferenceFormatted<T>(string name, bool roaming, T defaultValue = default, string? format = null)
+    {
         try
         {
-            builder.Append(CommandController.Current.Log.GetSummary(currentTime.LocalDateTime));
+            var preferences = IPreferences.Current;
+
+            if (preferences == null)
+                return "{ Preferences are null }";
+            
+            var value = roaming
+                ? preferences.GetPreference(name, defaultValue)
+                : preferences.GetLocalPreference(name, defaultValue);
+
+            return FormatObject(value, format);
         }
-        catch (Exception cemLogException)
+        catch (Exception e)
         {
-            builder.AppendLine($"Error ({cemLogException.GetType().FullName}: {cemLogException.Message}) while gathering command log, skipping...");
+            return $$"""{ Failed getting preference: {{e.Message}} }""";
         }
-        
-        builder.AppendLine("\n-----------State-----------");
+    }
 
+    private static string GetFormatted(Func<object?> getter, string? format = null)
+    {
         try
         {
-            builder.AppendLine($"Current Tool: {ViewModelMain.Current?.ToolsSubViewModel?.ActiveTool}");
-            builder.AppendLine($"Autosaving Enabled: {IPreferences.Current.GetPreference(PreferencesConstants.AutosavePeriodMinutes, PreferencesConstants.AutosavePeriodDefault).ToString(CultureInfo.InvariantCulture)}");
+            var value = getter();
+
+            return FormatObject(value, format);
         }
-        catch (Exception stateException)
+        catch (Exception e)
         {
-            builder.AppendLine($"Error ({stateException.GetType().FullName}: {stateException.Message}) while gathering command log, skipping...");
+            return $$"""{ Failed retrieving: {{e.Message}} }""";
         }
-        
-        builder.AppendLine("\n-----------Exception-----------");
-
-        CrashHelper.AddExceptionMessage(builder, exception);
-
-        string filename = $"crash-{currentTime:yyyy-MM-dd_HH-mm-ss_fff}.zip";
-        string path = Path.Combine(
-            Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
-            "PixiEditor",
-            "crash_logs");
-        Directory.CreateDirectory(path);
+    }
 
-        CrashReport report = new();
-        report.FilePath = Path.Combine(path, filename);
-        report.ReportText = builder.ToString();
+    private static string FormatObject(object? value, string? format)
+    {
+        return value switch
+        {
+            null => "null",
+            IFormattable formattable => formattable.ToString(format, CultureInfo.InvariantCulture),
+            LocalizedString localizedS => FormatLocalizedString(localizedS),
+            string s => $"\"{s}\"",
+            _ => value.ToString()
+        };
 
-        return report;
+        string FormatLocalizedString(LocalizedString localizedS)
+        {
+            return localizedS.Parameters != null
+                ? $"{localizedS.Key} @({string.Join(", ", localizedS.Parameters.Select(x => FormatObject(x, format)))})" 
+                : localizedS.Key;
+        }
     }
 
     public static CrashReport Parse(string path)

+ 5 - 1
src/PixiEditor/Views/Dialogs/SendCrashReportWindow.xaml.cs

@@ -46,7 +46,11 @@ internal partial class SendCrashReportWindow : Window
 
         foreach (var file in info.EnumerateFiles())
         {
-            file.Delete();
+            try
+            {
+                file.Delete();
+            }
+            catch { }
         }
 
         File.Copy(report.FilePath, Path.Combine(tempPath, Path.GetFileName(report.FilePath)), true);