feat(claude-do): UI-Prozess loggt auf Platte (ui-.log) + fehlgeschlagene Hub-

## Problem
Beim DeleteTask-Bug (Fix 352aaa52) gab es null Spuren: Der UI-Prozess (ClaudeDo.App) hat gar kein File-Logging (weder Serilog noch `Microsoft.Extensions.Logging` sind in App/Ui referenziert), und im Worker loggt SignalR fehlgeschlagene Hub-Invocations nur auf Debug (`Microsoft.AspNetCore` steht in `src/ClaudeDo.Worker/Program.cs` Z. 60 auf Warning). Die Ursache ließ sich nur finden, ind

ClaudeDo-Task: d2ae3831-733f-4d40-93d7-70c93da11590
This commit is contained in:
Mika Kuns
2026-09-28 13:27:21 +02:00
parent 352aaa525b
commit 57dd676672
8 changed files with 93 additions and 2 deletions
+1
View File
@@ -52,6 +52,7 @@ public partial class App : Application
Dispatcher.UIThread.UnhandledException += (_, e) =>
{
e.Handled = true;
Serilog.Log.Error(e.Exception, "Unhandled exception on the UI dispatcher");
shell.FlashFooterError(Loc.T("vm.shell.unexpectedError", e.Exception.Message));
};
+2
View File
@@ -26,6 +26,8 @@
</PackageReference>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="Serilog" Version="4.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
+33
View File
@@ -13,6 +13,7 @@ using ClaudeDo.Ui.ViewModels.Modals;
using ClaudeDo.Ui.ViewModels.Modals.Settings;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using System;
using System.Globalization;
using System.IO;
@@ -20,6 +21,7 @@ using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace ClaudeDo.App;
@@ -34,6 +36,35 @@ sealed class Program
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
SetCurrentProcessExplicitAppUserModelID("ClaudeDo.App");
var logRoot = Path.Combine(Paths.AppDataRoot(), "logs");
Directory.CreateDirectory(logRoot);
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.File(
Path.Combine(logRoot, "ui-.log"),
rollingInterval: RollingInterval.Day,
retainedFileCountLimit: 7,
shared: true)
.CreateLogger();
var version = Assembly.GetEntryAssembly()?
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion
?? "0.0.0";
Log.Information("ClaudeDo.App starting (version: {Version})", version);
// Last-resort net: any exception that misses every other handler still gets one
// Fatal line in the log before the process dies.
AppDomain.CurrentDomain.UnhandledException += (_, e) =>
{
Log.Fatal(e.ExceptionObject as Exception, "Unhandled exception, terminating (IsTerminating: {IsTerminating})", e.IsTerminating);
Log.CloseAndFlush();
};
TaskScheduler.UnobservedTaskException += (_, e) =>
{
Log.Error(e.Exception, "Unobserved task exception");
e.SetObserved();
};
var services = BuildServices();
using (var scope = services.CreateScope())
@@ -62,6 +93,8 @@ sealed class Program
{
/* best effort on shutdown */
}
Log.CloseAndFlush();
}
}