New: Report health error if Recycling Bin folder is not writable

Closes #4692
This commit is contained in:
Mark McDowall 2023-04-24 20:23:20 -07:00
parent 99c4f5b746
commit 8c50cd061e
5 changed files with 78 additions and 4 deletions

View File

@ -0,0 +1,38 @@
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.MediaFiles.Events;
namespace NzbDrone.Core.HealthCheck.Checks
{
[CheckOn(typeof(EpisodeImportedEvent), CheckOnCondition.FailedOnly)]
[CheckOn(typeof(EpisodeImportFailedEvent), CheckOnCondition.SuccessfulOnly)]
public class RecyclingBinCheck : HealthCheckBase
{
private readonly IConfigService _configService;
private readonly IDiskProvider _diskProvider;
public RecyclingBinCheck(IConfigService configService, IDiskProvider diskProvider)
{
_configService = configService;
_diskProvider = diskProvider;
}
public override HealthCheck Check()
{
var recycleBin = _configService.RecycleBin;
if (recycleBin.IsNullOrWhiteSpace())
{
return new HealthCheck(GetType());
}
if (!_diskProvider.FolderWritable(recycleBin))
{
return new HealthCheck(GetType(), HealthCheckResult.Error, $"Unable to write to configured recycling bin folder: {recycleBin}. Ensure this path exists and is writable by the user running Sonarr");
}
return new HealthCheck(GetType());
}
}
}

View File

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NLog; using NLog;

View File

@ -151,6 +151,13 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
_commandQueueManager.Push(new RescanSeriesCommand(localEpisode.Series.Id)); _commandQueueManager.Push(new RescanSeriesCommand(localEpisode.Series.Id));
} }
catch (RecycleBinException e)
{
_logger.Warn(e, "Couldn't import episode " + localEpisode);
_eventAggregator.PublishEvent(new EpisodeImportFailedEvent(e, localEpisode, newDownload, downloadClientItem));
importResults.Add(new ImportResult(importDecision, "Failed to import episode, unable to move existing file to the Recycle Bin."));
}
catch (Exception e) catch (Exception e)
{ {
_logger.Warn(e, "Couldn't import episode " + localEpisode); _logger.Warn(e, "Couldn't import episode " + localEpisode);

View File

@ -0,0 +1,28 @@
using System;
using System.IO;
using System.Runtime.Serialization;
namespace NzbDrone.Core.MediaFiles.EpisodeImport
{
public class RecycleBinException : DirectoryNotFoundException
{
public RecycleBinException()
{
}
public RecycleBinException(string message)
: base(message)
{
}
public RecycleBinException(string message, Exception innerException)
: base(message, innerException)
{
}
protected RecycleBinException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}

View File

@ -1,4 +1,4 @@
using System; using System;
using System.IO; using System.IO;
using NLog; using NLog;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
@ -6,6 +6,7 @@ using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.MediaFiles.Commands; using NzbDrone.Core.MediaFiles.Commands;
using NzbDrone.Core.MediaFiles.EpisodeImport;
using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Tv.Events; using NzbDrone.Core.Tv.Events;
@ -98,7 +99,7 @@ namespace NzbDrone.Core.MediaFiles
catch (IOException e) catch (IOException e)
{ {
_logger.Error(e, "Unable to create the folder '{0}' in the recycling bin for the file '{1}'", destinationFolder, fileInfo.Name); _logger.Error(e, "Unable to create the folder '{0}' in the recycling bin for the file '{1}'", destinationFolder, fileInfo.Name);
throw; throw new RecycleBinException($"Unable to create the folder '{destinationFolder}' in the recycling bin for the file '{fileInfo.Name}'", e);
} }
var index = 1; var index = 1;
@ -123,7 +124,7 @@ namespace NzbDrone.Core.MediaFiles
catch (IOException e) catch (IOException e)
{ {
_logger.Error(e, "Unable to move '{0}' to the recycling bin: '{1}'", path, destination); _logger.Error(e, "Unable to move '{0}' to the recycling bin: '{1}'", path, destination);
throw; throw new RecycleBinException($"Unable to move '{path}' to the recycling bin: '{destination}'", e);
} }
SetLastWriteTime(destination, DateTime.UtcNow); SetLastWriteTime(destination, DateTime.UtcNow);