chore: handle profile errors properly and stop being lazy

This commit is contained in:
goat 2023-10-10 19:16:42 +02:00
parent a096bd547f
commit 6a01c8cc5b
No known key found for this signature in database
GPG key ID: 49E2AA8C6A76498B
2 changed files with 60 additions and 13 deletions

View file

@ -789,9 +789,16 @@ internal partial class PluginManager : IDisposable, IServiceType
// If it was in multiple profiles and is still, the user uninstalled it and chose to keep it in there, // If it was in multiple profiles and is still, the user uninstalled it and chose to keep it in there,
// or the user removed the plugin manually in which case we don't care // or the user removed the plugin manually in which case we don't care
if (reason == PluginLoadReason.Installer) if (reason == PluginLoadReason.Installer)
{
try
{ {
// We don't need to apply, it doesn't matter // We don't need to apply, it doesn't matter
await this.profileManager.DefaultProfile.RemoveAsync(repoManifest.InternalName, false, false); await this.profileManager.DefaultProfile.RemoveAsync(repoManifest.InternalName, false);
}
catch (ProfileOperationException)
{
// ignored
}
} }
else else
{ {

View file

@ -200,22 +200,17 @@ internal class Profile
/// </summary> /// </summary>
/// <param name="internalName">The internal name of the plugin.</param> /// <param name="internalName">The internal name of the plugin.</param>
/// <param name="apply">Whether or not the current state should immediately be applied.</param> /// <param name="apply">Whether or not the current state should immediately be applied.</param>
/// <param name="guardrails">
/// Throw if certain operations are invalid.
/// * Throw if the plugin is not in this profile.
/// * If this is the default profile, check if we are in any other, then throw if we aren't.
/// </param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public async Task RemoveAsync(string internalName, bool apply = true, bool guardrails = true) public async Task RemoveAsync(string internalName, bool apply = true)
{ {
ProfileModelV1.ProfileModelV1Plugin entry; ProfileModelV1.ProfileModelV1Plugin entry;
lock (this) lock (this)
{ {
entry = this.modelV1.Plugins.FirstOrDefault(x => x.InternalName == internalName); entry = this.modelV1.Plugins.FirstOrDefault(x => x.InternalName == internalName);
if (entry == null && guardrails) if (entry == null)
throw new ArgumentException($"No plugin \"{internalName}\" in profile \"{this.Guid}\""); throw new PluginNotFoundException(internalName);
if (!this.modelV1.Plugins.Remove(entry) && guardrails) if (!this.modelV1.Plugins.Remove(entry))
throw new Exception("Couldn't remove plugin from model collection"); throw new Exception("Couldn't remove plugin from model collection");
} }
@ -226,9 +221,9 @@ internal class Profile
{ {
await this.manager.DefaultProfile.AddOrUpdateAsync(internalName, this.IsEnabled && entry.IsEnabled, false); await this.manager.DefaultProfile.AddOrUpdateAsync(internalName, this.IsEnabled && entry.IsEnabled, false);
} }
else if (guardrails) else
{ {
throw new Exception("Removed plugin from default profile, but wasn't in any other profile"); throw new PluginNotInDefaultProfileException(internalName);
} }
} }
@ -241,3 +236,48 @@ internal class Profile
/// <inheritdoc/> /// <inheritdoc/>
public override string ToString() => $"{this.Guid} ({this.Name})"; public override string ToString() => $"{this.Guid} ({this.Name})";
} }
/// <summary>
/// Exception indicating an issue during a profile operation.
/// </summary>
internal abstract class ProfileOperationException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="ProfileOperationException"/> class.
/// </summary>
/// <param name="message">Message to pass on.</param>
protected ProfileOperationException(string message)
: base(message)
{
}
}
/// <summary>
/// Exception indicating that a plugin was not found in the default profile.
/// </summary>
internal sealed class PluginNotInDefaultProfileException : ProfileOperationException
{
/// <summary>
/// Initializes a new instance of the <see cref="PluginNotInDefaultProfileException"/> class.
/// </summary>
/// <param name="internalName">The internal name of the plugin causing the error.</param>
public PluginNotInDefaultProfileException(string internalName)
: base($"The plugin '{internalName}' is not in the default profile, and cannot be removed")
{
}
}
/// <summary>
/// Exception indicating that the plugin was not found.
/// </summary>
internal sealed class PluginNotFoundException : ProfileOperationException
{
/// <summary>
/// Initializes a new instance of the <see cref="PluginNotFoundException"/> class.
/// </summary>
/// <param name="internalName">The internal name of the plugin causing the error.</param>
public PluginNotFoundException(string internalName)
: base($"The plugin '{internalName}' was not found in the profile")
{
}
}