## 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
72 lines
2.7 KiB
C#
72 lines
2.7 KiB
C#
using System;
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Controls.ApplicationLifetimes;
|
|
using Avalonia.Markup.Xaml;
|
|
using Avalonia.Threading;
|
|
using ClaudeDo.Ui;
|
|
using ClaudeDo.Ui.Localization;
|
|
using ClaudeDo.Ui.Services;
|
|
using ClaudeDo.Ui.ViewModels;
|
|
using ClaudeDo.Ui.Views;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
namespace ClaudeDo.App;
|
|
|
|
public partial class App : Application
|
|
{
|
|
private readonly IServiceProvider? _services;
|
|
|
|
// Parameterless ctor is required by the XAML previewer / designer.
|
|
public App() { }
|
|
|
|
public App(IServiceProvider services) => _services = services;
|
|
|
|
public override void Initialize()
|
|
{
|
|
AvaloniaXamlLoader.Load(this);
|
|
if (_services?.GetService<AppSettings>() is { } settings)
|
|
AccentPresetService.Apply(AccentPresets.Find(settings.AccentPreset));
|
|
}
|
|
|
|
public override void OnFrameworkInitializationCompleted()
|
|
{
|
|
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
{
|
|
var services = _services
|
|
?? throw new InvalidOperationException("App was constructed without a service provider.");
|
|
|
|
FocusClearing.Install();
|
|
|
|
// The main window is authoritative — closing it shuts the app down even if the
|
|
// modeless Mission Control window is still open.
|
|
desktop.ShutdownMode = ShutdownMode.OnMainWindowClose;
|
|
|
|
var shell = services.GetRequiredService<IslandsShellViewModel>();
|
|
|
|
// Last-resort backstop: an exception escaping a dispatcher job kills the process, and
|
|
// ClaudeDo hosts third-party UI (the ConPTY terminal control) whose async void key and
|
|
// render handlers have done exactly that — one bad keystroke took the whole app down,
|
|
// losing every open session. Swallowing is the lesser evil here: the failing job is
|
|
// already dead either way, and the user still gets told via the footer error strip.
|
|
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));
|
|
};
|
|
|
|
desktop.MainWindow = new MainWindow
|
|
{
|
|
DataContext = shell,
|
|
};
|
|
|
|
// Kick off the SignalR retry loop — reconnects indefinitely if the worker
|
|
// is not up yet, or goes down and comes back.
|
|
_ = services.GetRequiredService<WorkerClient>().StartAsync();
|
|
}
|
|
|
|
base.OnFrameworkInitializationCompleted();
|
|
}
|
|
}
|