From e4ab7cc8647fc2b05d48a5b3a5fd20d3101e5576 Mon Sep 17 00:00:00 2001 From: lars-berger Date: Thu, 2 Feb 2023 19:22:04 +0800 Subject: [PATCH] feat: add command history to error logs (#237) --- GlazeWM.Bootstrapper/Program.cs | 10 +++++++++- GlazeWM.Infrastructure/Bussing/Bus.cs | 7 +++++++ .../CommandHandlers/HandleFatalExceptionHandler.cs | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/GlazeWM.Bootstrapper/Program.cs b/GlazeWM.Bootstrapper/Program.cs index 45020cb7e..b9db405d4 100644 --- a/GlazeWM.Bootstrapper/Program.cs +++ b/GlazeWM.Bootstrapper/Program.cs @@ -2,12 +2,14 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Text.Json.Serialization; using System.Threading; using GlazeWM.Bar; using GlazeWM.Domain; using GlazeWM.Domain.Containers; using GlazeWM.Infrastructure; +using GlazeWM.Infrastructure.Bussing; using GlazeWM.Infrastructure.Exceptions; using GlazeWM.Infrastructure.Logging; using GlazeWM.Infrastructure.Serialization; @@ -69,7 +71,7 @@ private static IHost CreateHost(string[] args) // Configure exception handler. services .AddOptions() - .Configure((options, containerService, jsonService) => + .Configure((options, bus, containerService, jsonService) => { options.ErrorLogPath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), @@ -83,8 +85,14 @@ private static IHost CreateHost(string[] args) new List { new JsonContainerConverter() } ); + // History of latest command invocations. Most recent is first. + var commandHistory = bus.CommandHistory + .Select(command => command.Name) + .Reverse(); + return $"{DateTime.Now}\n" + $"{exception}\n" + + $"Command history: {string.Join(", ", commandHistory)} \n" + $"State dump: {stateDump}\n\n"; }; }); diff --git a/GlazeWM.Infrastructure/Bussing/Bus.cs b/GlazeWM.Infrastructure/Bussing/Bus.cs index 3ebffad71..46eba7135 100644 --- a/GlazeWM.Infrastructure/Bussing/Bus.cs +++ b/GlazeWM.Infrastructure/Bussing/Bus.cs @@ -13,6 +13,7 @@ namespace GlazeWM.Infrastructure.Bussing public sealed class Bus { public readonly Subject Events = new(); + public readonly Queue CommandHistory = new(); public readonly object LockObj = new(); private readonly ILogger _logger; @@ -30,6 +31,12 @@ public CommandResponse Invoke(T command) where T : Command { _logger.LogDebug("Command {CommandName} invoked.", command.Name); + CommandHistory.Enqueue(command); + + // Maintain a history of the last 15 command invocations for debugging. + if (CommandHistory.Count > 15) + CommandHistory.Dequeue(); + // Create a `Type` object representing the constructed `ICommandHandler` generic. var handlerType = typeof(ICommandHandler<>).MakeGenericType(command.GetType()); diff --git a/GlazeWM.Infrastructure/Common/CommandHandlers/HandleFatalExceptionHandler.cs b/GlazeWM.Infrastructure/Common/CommandHandlers/HandleFatalExceptionHandler.cs index 4587a565b..8afe4d999 100644 --- a/GlazeWM.Infrastructure/Common/CommandHandlers/HandleFatalExceptionHandler.cs +++ b/GlazeWM.Infrastructure/Common/CommandHandlers/HandleFatalExceptionHandler.cs @@ -23,6 +23,7 @@ public CommandResponse Handle(HandleFatalExceptionCommand command) { // Alert the user of the error. var exception = command.Exception; + // TODO: Show foreground window. MessageBox.Show($"Unhandled exception: {exception.Message}"); WriteToErrorLog(exception);