refactor: Consistent exception handling in all command classes

- Consistently use ExitStatus enum.
- Where appropriate, do not handle exceptions in isolation in the
  command class itself. Rather, let exceptions through to the entrypoint
  so the centralized exception handler can deal with them.
pull/351/head
Robert Dailey 3 months ago
parent a4bb339f07
commit a1358014ad

@ -2,5 +2,6 @@
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JsonStandardCompliance" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>

@ -1,6 +1,7 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using Recyclarr.Cli.Console.Settings;
using Recyclarr.Cli.Processors;
using Recyclarr.Cli.Processors.Config;
using Recyclarr.Repo;
using Spectre.Console.Cli;
@ -43,16 +44,15 @@ public class ConfigCreateCommand(ILogger log, IConfigCreationProcessor processor
{
await repoUpdater.UpdateAllRepositories(settings.CancellationToken);
processor.Process(settings);
return (int) ExitStatus.Succeeded;
}
catch (FileExistsException e)
{
log.Error(e,
"The file {ConfigFile} already exists. Please choose another path or " +
"delete/move the existing file and run this command again", e.AttemptedPath);
return 1;
}
return 0;
return (int) ExitStatus.Failed;
}
}

@ -1,7 +1,7 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using Recyclarr.Cli.Processors;
using Recyclarr.Cli.Processors.Config;
using Recyclarr.Config.Parsing.ErrorHandling;
using Recyclarr.Repo;
using Spectre.Console.Cli;
@ -9,7 +9,7 @@ namespace Recyclarr.Cli.Console.Commands;
[UsedImplicitly]
[Description("List local configuration files.")]
public class ConfigListLocalCommand(ILogger log, ConfigListLocalProcessor processor, IMultiRepoUpdater repoUpdater)
public class ConfigListLocalCommand(ConfigListLocalProcessor processor, IMultiRepoUpdater repoUpdater)
: AsyncCommand<ConfigListLocalCommand.CliSettings>
{
[SuppressMessage("Design", "CA1034:Nested types should not be visible")]
@ -17,17 +17,8 @@ public class ConfigListLocalCommand(ILogger log, ConfigListLocalProcessor proces
public override async Task<int> ExecuteAsync(CommandContext context, CliSettings settings)
{
try
{
await repoUpdater.UpdateAllRepositories(settings.CancellationToken);
processor.Process();
return 0;
}
catch (NoConfigurationFilesException e)
{
log.Error(e, "Unable to list local config files");
}
return 1;
await repoUpdater.UpdateAllRepositories(settings.CancellationToken);
processor.Process();
return (int) ExitStatus.Succeeded;
}
}

@ -1,7 +1,7 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using Recyclarr.Cli.Processors;
using Recyclarr.Cli.Processors.Config;
using Recyclarr.Config.Parsing.ErrorHandling;
using Recyclarr.Repo;
using Spectre.Console.Cli;
@ -9,10 +9,7 @@ namespace Recyclarr.Cli.Console.Commands;
[UsedImplicitly]
[Description("List local configuration files.")]
public class ConfigListTemplatesCommand(
ILogger log,
ConfigListTemplateProcessor processor,
IMultiRepoUpdater repoUpdater)
public class ConfigListTemplatesCommand(ConfigListTemplateProcessor processor, IMultiRepoUpdater repoUpdater)
: AsyncCommand<ConfigListTemplatesCommand.CliSettings>
{
[SuppressMessage("Design", "CA1034:Nested types should not be visible")]
@ -27,18 +24,9 @@ public class ConfigListTemplatesCommand(
public override async Task<int> ExecuteAsync(CommandContext context, CliSettings settings)
{
try
{
await repoUpdater.UpdateAllRepositories(settings.CancellationToken);
processor.Process(settings);
return 0;
}
catch (NoConfigurationFilesException e)
{
log.Error(e, "Unable to list template files");
}
return 1;
await repoUpdater.UpdateAllRepositories(settings.CancellationToken);
processor.Process(settings);
return (int) ExitStatus.Succeeded;
}
}

@ -3,16 +3,13 @@ using System.Diagnostics.CodeAnalysis;
using Recyclarr.Cli.Console.Settings;
using Recyclarr.Cli.Processors;
using Recyclarr.Cli.Processors.Delete;
using Recyclarr.Cli.Processors.ErrorHandling;
using Spectre.Console.Cli;
namespace Recyclarr.Cli.Console.Commands;
[Description("Delete things from services like Radarr & Sonarr")]
[Description("Delete things from services like Radarr and Sonarr")]
[UsedImplicitly]
public class DeleteCustomFormatsCommand(
IDeleteCustomFormatsProcessor processor,
ConsoleExceptionHandler exceptionHandler)
public class DeleteCustomFormatsCommand(IDeleteCustomFormatsProcessor processor)
: AsyncCommand<DeleteCustomFormatsCommand.CliSettings>
{
[UsedImplicitly]
@ -46,21 +43,7 @@ public class DeleteCustomFormatsCommand(
[SuppressMessage("Design", "CA1031:Do not catch general exception types")]
public override async Task<int> ExecuteAsync(CommandContext context, CliSettings settings)
{
try
{
await processor.Process(settings, settings.CancellationToken);
}
catch (Exception e)
{
if (!await exceptionHandler.HandleException(e))
{
// This means we didn't handle the exception; rethrow it.
throw;
}
return (int) ExitStatus.Failed;
}
await processor.Process(settings, settings.CancellationToken);
return (int) ExitStatus.Succeeded;
}
}

@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis;
using Recyclarr.Cli.Console.Helpers;
using Recyclarr.Cli.Console.Settings;
using Recyclarr.Cli.Pipelines.CustomFormat;
using Recyclarr.Cli.Processors;
using Recyclarr.Repo;
using Recyclarr.TrashGuide;
using Spectre.Console.Cli;
@ -38,6 +39,6 @@ public class ListCustomFormatsCommand(CustomFormatDataLister lister, IMultiRepoU
{
await repoUpdater.UpdateAllRepositories(settings.CancellationToken, settings.Raw);
lister.List(settings);
return 0;
return (int) ExitStatus.Succeeded;
}
}

@ -2,6 +2,7 @@ using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using Recyclarr.Cli.Console.Helpers;
using Recyclarr.Cli.Pipelines.MediaNaming;
using Recyclarr.Cli.Processors;
using Recyclarr.Repo;
using Recyclarr.TrashGuide;
using Spectre.Console.Cli;
@ -27,6 +28,6 @@ public class ListMediaNamingCommand(MediaNamingDataLister lister, IMultiRepoUpda
{
await repoUpdater.UpdateAllRepositories(settings.CancellationToken);
lister.ListNaming(settings.Service);
return 0;
return (int) ExitStatus.Succeeded;
}
}

@ -2,6 +2,7 @@ using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using Recyclarr.Cli.Console.Helpers;
using Recyclarr.Cli.Pipelines.QualitySize;
using Recyclarr.Cli.Processors;
using Recyclarr.Repo;
using Recyclarr.TrashGuide;
using Spectre.Console.Cli;
@ -28,6 +29,6 @@ public class ListQualitiesCommand(QualitySizeDataLister lister, IMultiRepoUpdate
{
await repoUpdater.UpdateAllRepositories(settings.CancellationToken);
lister.ListQualities(settings.Service);
return 0;
return (int) ExitStatus.Succeeded;
}
}

@ -2,6 +2,7 @@ using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using Recyclarr.Cli.Migration;
using Recyclarr.Cli.Processors;
using Spectre.Console;
using Spectre.Console.Cli;
@ -25,6 +26,7 @@ public class MigrateCommand(
{
migration.PerformAllMigrationSteps(settings.Debug);
console.WriteLine("All migration steps completed");
return (int) ExitStatus.Succeeded;
}
catch (MigrationException e)
{
@ -44,14 +46,12 @@ public class MigrateCommand(
}
console.Write(msg.ToString());
return 1;
}
catch (RequiredMigrationException ex)
{
console.WriteLine($"ERROR: {ex.Message}");
return 1;
}
return 0;
return (int) ExitStatus.Failed;
}
}

@ -42,7 +42,11 @@ internal static class Program
{
var log = scope.Resolve<ILogger>();
var exceptionHandler = new ConsoleExceptionHandler(log);
await exceptionHandler.HandleException(e);
if (!await exceptionHandler.HandleException(e))
{
log.Error(e, "Exiting due to fatal error");
}
return (int) ExitStatus.Failed;
}
}

Loading…
Cancel
Save