mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Plugins UI - Improved error reporting on exceptions during enable
This commit is contained in:
parent
4e8d0bf70b
commit
66b1620441
@ -11,7 +11,7 @@ namespace Artemis.Core
|
|||||||
public abstract class PluginFeature : CorePropertyChanged, IDisposable
|
public abstract class PluginFeature : CorePropertyChanged, IDisposable
|
||||||
{
|
{
|
||||||
private bool _isEnabled;
|
private bool _isEnabled;
|
||||||
private Exception? _loadException;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin feature info related to this feature
|
/// Gets the plugin feature info related to this feature
|
||||||
@ -37,15 +37,6 @@ namespace Artemis.Core
|
|||||||
internal set => SetAndNotify(ref _isEnabled, value);
|
internal set => SetAndNotify(ref _isEnabled, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the exception thrown while loading
|
|
||||||
/// </summary>
|
|
||||||
public Exception? LoadException
|
|
||||||
{
|
|
||||||
get => _loadException;
|
|
||||||
internal set => SetAndNotify(ref _loadException, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the identifier of this plugin feature
|
/// Gets the identifier of this plugin feature
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -149,10 +140,10 @@ namespace Artemis.Core
|
|||||||
if (isAutoEnable && GetLockFileCreated())
|
if (isAutoEnable && GetLockFileCreated())
|
||||||
{
|
{
|
||||||
// Don't wrap existing lock exceptions, simply rethrow them
|
// Don't wrap existing lock exceptions, simply rethrow them
|
||||||
if (LoadException is ArtemisPluginLockException)
|
if (Info.LoadException is ArtemisPluginLockException)
|
||||||
throw LoadException;
|
throw Info.LoadException;
|
||||||
|
|
||||||
throw new ArtemisPluginLockException(LoadException);
|
throw new ArtemisPluginLockException(Info.LoadException);
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateLockFile();
|
CreateLockFile();
|
||||||
@ -165,21 +156,21 @@ namespace Artemis.Core
|
|||||||
if (!enableTask.Wait(TimeSpan.FromSeconds(15)))
|
if (!enableTask.Wait(TimeSpan.FromSeconds(15)))
|
||||||
throw new ArtemisPluginException(Plugin, "Plugin load timeout");
|
throw new ArtemisPluginException(Plugin, "Plugin load timeout");
|
||||||
|
|
||||||
LoadException = null;
|
Info.LoadException = null;
|
||||||
OnEnabled();
|
OnEnabled();
|
||||||
}
|
}
|
||||||
// If enable failed, put it back in a disabled state
|
// If enable failed, put it back in a disabled state
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
IsEnabled = false;
|
IsEnabled = false;
|
||||||
LoadException = e;
|
Info.LoadException = e;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// Clean up the lock file unless the failure was due to the lock file
|
// Clean up the lock file unless the failure was due to the lock file
|
||||||
// After all, we failed but not miserably :)
|
// After all, we failed but not miserably :)
|
||||||
if (!(LoadException is ArtemisPluginLockException))
|
if (Info.LoadException is not ArtemisPluginLockException)
|
||||||
DeleteLockFile();
|
DeleteLockFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ namespace Artemis.Core
|
|||||||
[JsonObject(MemberSerialization.OptIn)]
|
[JsonObject(MemberSerialization.OptIn)]
|
||||||
public class PluginFeatureInfo : CorePropertyChanged, IPrerequisitesSubject
|
public class PluginFeatureInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||||
{
|
{
|
||||||
|
private Exception? _loadException;
|
||||||
private string? _description;
|
private string? _description;
|
||||||
private string? _icon;
|
private string? _icon;
|
||||||
private PluginFeature? _instance;
|
private PluginFeature? _instance;
|
||||||
@ -80,6 +81,15 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Type FeatureType { get; }
|
public Type FeatureType { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the exception thrown while loading
|
||||||
|
/// </summary>
|
||||||
|
public Exception? LoadException
|
||||||
|
{
|
||||||
|
get => _loadException;
|
||||||
|
internal set => SetAndNotify(ref _loadException, value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the plugin
|
/// The name of the plugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -426,6 +426,7 @@ namespace Artemis.Core.Services
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.Warning(new ArtemisPluginException(plugin, "Failed to instantiate feature", e), "Failed to instantiate feature", plugin);
|
_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),
|
new ArtemisPluginException(pluginFeature.Plugin, $"Exception during SetEnabled(true) on {pluginFeature}", e),
|
||||||
"Failed to enable plugin"
|
"Failed to enable plugin"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!isAutoEnable)
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:Artemis.UI.Screens.Settings"
|
xmlns:local="clr-namespace:Artemis.UI.Screens.Settings"
|
||||||
xmlns:s="https://github.com/canton7/Stylet"
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450" d:DesignWidth="800"
|
d:DesignHeight="450" d:DesignWidth="800"
|
||||||
d:DataContext="{d:DesignInstance local:SettingsTabsViewModel}">
|
d:DataContext="{d:DesignInstance local:SettingsTabsViewModel}">
|
||||||
@ -16,6 +17,7 @@
|
|||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
<Grid>
|
||||||
<TabControl Style="{StaticResource MaterialDesignAppBarTabControl}"
|
<TabControl Style="{StaticResource MaterialDesignAppBarTabControl}"
|
||||||
ItemsSource="{Binding Items}"
|
ItemsSource="{Binding Items}"
|
||||||
SelectedItem="{Binding ActiveItem}"
|
SelectedItem="{Binding ActiveItem}"
|
||||||
@ -30,4 +32,16 @@
|
|||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</TabControl.ContentTemplate>
|
</TabControl.ContentTemplate>
|
||||||
</TabControl>
|
</TabControl>
|
||||||
|
|
||||||
|
<!-- Bug: materialDesign:RippleAssist.RippleOnTop doesn't look as nice but otherwise it doesn't work at all, not sure why -->
|
||||||
|
<Button Style="{StaticResource MaterialDesignIconForegroundButton}"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
ToolTip="Open debugger"
|
||||||
|
Command="{s:Action ShowDebugger}"
|
||||||
|
materialDesign:RippleAssist.RippleOnTop="True">
|
||||||
|
<materialDesign:PackIcon Kind="Matrix" />
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@ -2,18 +2,23 @@
|
|||||||
using Artemis.UI.Screens.Settings.Tabs.Devices;
|
using Artemis.UI.Screens.Settings.Tabs.Devices;
|
||||||
using Artemis.UI.Screens.Settings.Tabs.General;
|
using Artemis.UI.Screens.Settings.Tabs.General;
|
||||||
using Artemis.UI.Screens.Settings.Tabs.Plugins;
|
using Artemis.UI.Screens.Settings.Tabs.Plugins;
|
||||||
|
using Artemis.UI.Services;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Settings
|
namespace Artemis.UI.Screens.Settings
|
||||||
{
|
{
|
||||||
public class SettingsTabsViewModel : Conductor<Screen>.Collection.OneActive
|
public class SettingsTabsViewModel : Conductor<Screen>.Collection.OneActive
|
||||||
{
|
{
|
||||||
|
private readonly IDebugService _debugService;
|
||||||
|
|
||||||
public SettingsTabsViewModel(
|
public SettingsTabsViewModel(
|
||||||
GeneralSettingsTabViewModel generalSettingsTabViewModel,
|
GeneralSettingsTabViewModel generalSettingsTabViewModel,
|
||||||
PluginSettingsTabViewModel pluginSettingsTabViewModel,
|
PluginSettingsTabViewModel pluginSettingsTabViewModel,
|
||||||
DeviceSettingsTabViewModel deviceSettingsTabViewModel,
|
DeviceSettingsTabViewModel deviceSettingsTabViewModel,
|
||||||
AboutTabViewModel aboutTabViewModel)
|
AboutTabViewModel aboutTabViewModel,
|
||||||
|
IDebugService debugService)
|
||||||
{
|
{
|
||||||
|
_debugService = debugService;
|
||||||
DisplayName = "Settings";
|
DisplayName = "Settings";
|
||||||
|
|
||||||
Items.Add(generalSettingsTabViewModel);
|
Items.Add(generalSettingsTabViewModel);
|
||||||
@ -23,5 +28,10 @@ namespace Artemis.UI.Screens.Settings
|
|||||||
|
|
||||||
ActiveItem = generalSettingsTabViewModel;
|
ActiveItem = generalSettingsTabViewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ShowDebugger()
|
||||||
|
{
|
||||||
|
_debugService.ShowDebugger();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,7 +37,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PluginFeatureInfo FeatureInfo { get; }
|
public PluginFeatureInfo FeatureInfo { get; }
|
||||||
public Exception LoadException => FeatureInfo.Instance?.LoadException;
|
public Exception LoadException => FeatureInfo.LoadException;
|
||||||
|
|
||||||
public bool ShowShield { get; }
|
public bool ShowShield { get; }
|
||||||
|
|
||||||
@ -119,12 +119,19 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
|
|
||||||
private async Task UpdateEnabled(bool enable)
|
private async Task UpdateEnabled(bool enable)
|
||||||
{
|
{
|
||||||
if (IsEnabled == enable || FeatureInfo.Instance == null)
|
if (IsEnabled == enable)
|
||||||
{
|
{
|
||||||
NotifyOfPropertyChange(nameof(IsEnabled));
|
NotifyOfPropertyChange(nameof(IsEnabled));
|
||||||
return;
|
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)
|
if (enable)
|
||||||
{
|
{
|
||||||
Enabling = true;
|
Enabling = true;
|
||||||
@ -156,7 +163,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
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
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user