diff --git a/src/Artemis.Core/Plugins/PluginFeature.cs b/src/Artemis.Core/Plugins/PluginFeature.cs index 983f20438..ef3917ba0 100644 --- a/src/Artemis.Core/Plugins/PluginFeature.cs +++ b/src/Artemis.Core/Plugins/PluginFeature.cs @@ -11,7 +11,7 @@ namespace Artemis.Core public abstract class PluginFeature : CorePropertyChanged, IDisposable { private bool _isEnabled; - private Exception? _loadException; + /// /// Gets the plugin feature info related to this feature @@ -37,15 +37,6 @@ namespace Artemis.Core internal set => SetAndNotify(ref _isEnabled, value); } - /// - /// Gets the exception thrown while loading - /// - public Exception? LoadException - { - get => _loadException; - internal set => SetAndNotify(ref _loadException, value); - } - /// /// Gets the identifier of this plugin feature /// @@ -149,10 +140,10 @@ namespace Artemis.Core if (isAutoEnable && GetLockFileCreated()) { // Don't wrap existing lock exceptions, simply rethrow them - if (LoadException is ArtemisPluginLockException) - throw LoadException; + if (Info.LoadException is ArtemisPluginLockException) + throw Info.LoadException; - throw new ArtemisPluginLockException(LoadException); + throw new ArtemisPluginLockException(Info.LoadException); } CreateLockFile(); @@ -165,21 +156,21 @@ namespace Artemis.Core if (!enableTask.Wait(TimeSpan.FromSeconds(15))) throw new ArtemisPluginException(Plugin, "Plugin load timeout"); - LoadException = null; + Info.LoadException = null; OnEnabled(); } // If enable failed, put it back in a disabled state catch (Exception e) { IsEnabled = false; - LoadException = e; + Info.LoadException = e; throw; } finally { // Clean up the lock file unless the failure was due to the lock file // After all, we failed but not miserably :) - if (!(LoadException is ArtemisPluginLockException)) + if (Info.LoadException is not ArtemisPluginLockException) DeleteLockFile(); } } diff --git a/src/Artemis.Core/Plugins/PluginFeatureInfo.cs b/src/Artemis.Core/Plugins/PluginFeatureInfo.cs index 4947ab20a..62b4a6c5c 100644 --- a/src/Artemis.Core/Plugins/PluginFeatureInfo.cs +++ b/src/Artemis.Core/Plugins/PluginFeatureInfo.cs @@ -17,6 +17,7 @@ namespace Artemis.Core [JsonObject(MemberSerialization.OptIn)] public class PluginFeatureInfo : CorePropertyChanged, IPrerequisitesSubject { + private Exception? _loadException; private string? _description; private string? _icon; private PluginFeature? _instance; @@ -80,6 +81,15 @@ namespace Artemis.Core /// public Type FeatureType { get; } + /// + /// Gets the exception thrown while loading + /// + public Exception? LoadException + { + get => _loadException; + internal set => SetAndNotify(ref _loadException, value); + } + /// /// The name of the plugin /// diff --git a/src/Artemis.Core/Services/PluginManagementService.cs b/src/Artemis.Core/Services/PluginManagementService.cs index bcd647d9a..de01c754f 100644 --- a/src/Artemis.Core/Services/PluginManagementService.cs +++ b/src/Artemis.Core/Services/PluginManagementService.cs @@ -426,6 +426,7 @@ namespace Artemis.Core.Services catch (Exception e) { _logger.Warning(new ArtemisPluginException(plugin, "Failed to instantiate feature", e), "Failed to instantiate feature", plugin); + featureInfo.LoadException = e; } } @@ -613,6 +614,9 @@ namespace Artemis.Core.Services new ArtemisPluginException(pluginFeature.Plugin, $"Exception during SetEnabled(true) on {pluginFeature}", e), "Failed to enable plugin" ); + + if (!isAutoEnable) + throw; } finally { diff --git a/src/Artemis.UI/Screens/Settings/SettingsTabsView.xaml b/src/Artemis.UI/Screens/Settings/SettingsTabsView.xaml index 4b4908289..5c0c68c7a 100644 --- a/src/Artemis.UI/Screens/Settings/SettingsTabsView.xaml +++ b/src/Artemis.UI/Screens/Settings/SettingsTabsView.xaml @@ -5,6 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Artemis.UI.Screens.Settings" xmlns:s="https://github.com/canton7/Stylet" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance local:SettingsTabsViewModel}"> @@ -16,18 +17,31 @@ - - - - - - - + + + + + + + + + + + + + diff --git a/src/Artemis.UI/Screens/Settings/SettingsTabsViewModel.cs b/src/Artemis.UI/Screens/Settings/SettingsTabsViewModel.cs index b85fd4c8e..fd3cbb27c 100644 --- a/src/Artemis.UI/Screens/Settings/SettingsTabsViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/SettingsTabsViewModel.cs @@ -2,18 +2,23 @@ using Artemis.UI.Screens.Settings.Tabs.Devices; using Artemis.UI.Screens.Settings.Tabs.General; using Artemis.UI.Screens.Settings.Tabs.Plugins; +using Artemis.UI.Services; using Stylet; namespace Artemis.UI.Screens.Settings { public class SettingsTabsViewModel : Conductor.Collection.OneActive { + private readonly IDebugService _debugService; + public SettingsTabsViewModel( GeneralSettingsTabViewModel generalSettingsTabViewModel, PluginSettingsTabViewModel pluginSettingsTabViewModel, DeviceSettingsTabViewModel deviceSettingsTabViewModel, - AboutTabViewModel aboutTabViewModel) + AboutTabViewModel aboutTabViewModel, + IDebugService debugService) { + _debugService = debugService; DisplayName = "Settings"; Items.Add(generalSettingsTabViewModel); @@ -23,5 +28,10 @@ namespace Artemis.UI.Screens.Settings ActiveItem = generalSettingsTabViewModel; } + + public void ShowDebugger() + { + _debugService.ShowDebugger(); + } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureViewModel.cs index 97ca37389..542a24c5a 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureViewModel.cs @@ -37,7 +37,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins } public PluginFeatureInfo FeatureInfo { get; } - public Exception LoadException => FeatureInfo.Instance?.LoadException; + public Exception LoadException => FeatureInfo.LoadException; public bool ShowShield { get; } @@ -81,7 +81,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins public async Task InstallPrerequisites() { if (FeatureInfo.Prerequisites.Any()) - await PluginPrerequisitesInstallDialogViewModel.Show(_dialogService, new List { FeatureInfo }); + await PluginPrerequisitesInstallDialogViewModel.Show(_dialogService, new List {FeatureInfo}); } public async Task RemovePrerequisites() @@ -119,12 +119,19 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins private async Task UpdateEnabled(bool enable) { - if (IsEnabled == enable || FeatureInfo.Instance == null) + if (IsEnabled == enable) { NotifyOfPropertyChange(nameof(IsEnabled)); return; } + if (FeatureInfo.Instance == null) + { + NotifyOfPropertyChange(nameof(IsEnabled)); + _messageService.ShowMessage($"Feature '{FeatureInfo.Name}' is in a broken state and cannot enable.", "VIEW LOGS", ShowLogsFolder); + return; + } + if (enable) { Enabling = true; @@ -144,7 +151,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins // Check if all prerequisites are met async if (!FeatureInfo.ArePrerequisitesMet()) { - await PluginPrerequisitesInstallDialogViewModel.Show(_dialogService, new List { FeatureInfo }); + await PluginPrerequisitesInstallDialogViewModel.Show(_dialogService, new List {FeatureInfo}); if (!FeatureInfo.ArePrerequisitesMet()) { NotifyOfPropertyChange(nameof(IsEnabled)); @@ -156,7 +163,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins } catch (Exception e) { - _messageService.ShowMessage($"Failed to enable {FeatureInfo.Name}\r\n{e.Message}", "VIEW LOGS", ShowLogsFolder); + _messageService.ShowMessage($"Failed to enable '{FeatureInfo.Name}'.\r\n{e.Message}", "VIEW LOGS", ShowLogsFolder); } finally {