From fe0003e55fb087ae5a4e69aaae33bbaa8b8fca72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Kov=C3=A1cs?= Date: Thu, 3 Aug 2023 11:56:08 +0200 Subject: [PATCH] Startup error handling --- .../ViewModels/IMainWindowViewModel.cs | 1 - .../ViewModels/IMainWindowViewModelBase.cs | 4 +++ .../ViewModels/MainWindowLoadingViewModel.cs | 3 ++ .../ViewModels/MainWindowViewModel.cs | 10 +++++-- .../FileTime.GuiApp/Views/MainWindow.axaml | 9 ++++-- .../FileTime.GuiApp/Views/MainWindow.axaml.cs | 29 ++++++++++++++----- 6 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/IMainWindowViewModel.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/IMainWindowViewModel.cs index f6e4f87..4b0578d 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/IMainWindowViewModel.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/IMainWindowViewModel.cs @@ -9,7 +9,6 @@ namespace FileTime.GuiApp.ViewModels; public interface IMainWindowViewModel : IMainWindowViewModelBase { - string Title { get; } IGuiAppState AppState { get; } IItemPreviewService ItemPreviewService { get; } IDialogService DialogService { get; } diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/IMainWindowViewModelBase.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/IMainWindowViewModelBase.cs index 16121fb..ca97507 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/IMainWindowViewModelBase.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/IMainWindowViewModelBase.cs @@ -1,7 +1,11 @@ +using DeclarativeProperty; + namespace FileTime.GuiApp.ViewModels; public interface IMainWindowViewModelBase { + DeclarativeProperty Title { get; } bool Loading { get; } IObservable MainFont { get; } + DeclarativeProperty FatalError { get; } } \ No newline at end of file diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/MainWindowLoadingViewModel.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/MainWindowLoadingViewModel.cs index d4125d4..0995787 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/MainWindowLoadingViewModel.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/MainWindowLoadingViewModel.cs @@ -1,4 +1,5 @@ using System.Reactive.Subjects; +using DeclarativeProperty; namespace FileTime.GuiApp.ViewModels; @@ -6,4 +7,6 @@ public class MainWindowLoadingViewModel : IMainWindowViewModelBase { public bool Loading => true; public IObservable MainFont { get; } = new BehaviorSubject(""); + public DeclarativeProperty Title { get; } = new("Loading..."); + public DeclarativeProperty FatalError { get; } = new(); } \ No newline at end of file diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/MainWindowViewModel.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/MainWindowViewModel.cs index 08df503..57d00da 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/MainWindowViewModel.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/MainWindowViewModel.cs @@ -1,6 +1,7 @@ using System.Reactive.Linq; using System.Reflection; using Avalonia.Input; +using DeclarativeProperty; using FileTime.App.CommandPalette.Services; using FileTime.App.Core.Services; using FileTime.App.Core.UserCommand; @@ -38,8 +39,9 @@ public partial class MainWindowViewModel : IMainWindowViewModel { public bool Loading => false; public IObservable MainFont => _fontService.MainFont.Select(x => x ?? ""); + public DeclarativeProperty FatalError { get; } = new(); public IGuiAppState AppState => _appState; - public string Title { get; private set; } + public DeclarativeProperty Title { get; } = new(); public Action? FocusDefaultElement { get; set; } partial void OnInitialize() @@ -57,10 +59,12 @@ public partial class MainWindowViewModel : IMainWindowViewModel } } - Title = "FileTime " + versionString; + var title = "FileTime " + versionString; #if DEBUG - Title += " (Debug)"; + title += " (Debug)"; #endif + + Title.SetValueSafe(title); _modalService.AllModalClosed += (_, _) => FocusDefaultElement?.Invoke(); diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml b/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml index 6b7940b..e5654e9 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml @@ -53,7 +53,7 @@ - + @@ -998,7 +998,12 @@ + Text="{Binding Title.Value}" /> + diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml.cs index 186217b..ca737e3 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml.cs @@ -75,9 +75,22 @@ public partial class MainWindow : Window, IUiAccessor _logger?.LogInformation( $"{nameof(MainWindow)} opened, starting {nameof(MainWindowViewModel)} initialization..."); - var viewModel = DI.ServiceProvider.GetRequiredService(); - viewModel.FocusDefaultElement = () => Focus(); - ViewModel = viewModel; + try + { + var viewModel = DI.ServiceProvider.GetRequiredService(); + viewModel.FocusDefaultElement = () => Focus(); + ViewModel = viewModel; + } + catch (Exception ex) + { + _logger?.LogError(ex, "Error initializing {ViewModel}", nameof(MainWindowViewModel)); + if (DataContext is IMainWindowViewModelBase mainWindowViewModelBase) + { + mainWindowViewModelBase.FatalError.SetValueSafe( + $"Error initializing {nameof(MainWindowViewModel)}: " + ex.Message + ); + } + } } } @@ -187,9 +200,9 @@ public partial class MainWindow : Window, IUiAccessor private async void Child_OnPointerPressed(object? sender, PointerPressedEventArgs e) { - if (e is {Handled: false, ClickCount: 2} - && ViewModel != null - && e.GetCurrentPoint(this).Properties.IsLeftButtonPressed + if (e is {Handled: false, ClickCount: 2} + && ViewModel != null + && e.GetCurrentPoint(this).Properties.IsLeftButtonPressed && sender is StyledElement {DataContext: IItemViewModel itemViewModel}) { try @@ -199,8 +212,8 @@ public partial class MainWindow : Window, IUiAccessor catch (Exception ex) { _logger?.LogError( - ex, - "Error while opening item {Item}", + ex, + "Error while opening item {Item}", itemViewModel.BaseItem?.FullName?.Path ?? itemViewModel.DisplayNameText ); }