diff --git a/ErsatzTV.Core/Interfaces/Metadata/ILocalStatisticsProvider.cs b/ErsatzTV.Core/Interfaces/Metadata/ILocalStatisticsProvider.cs index c1b480c64..1fce8a79c 100644 --- a/ErsatzTV.Core/Interfaces/Metadata/ILocalStatisticsProvider.cs +++ b/ErsatzTV.Core/Interfaces/Metadata/ILocalStatisticsProvider.cs @@ -1,10 +1,11 @@ using System.Threading.Tasks; using ErsatzTV.Core.Domain; +using LanguageExt; namespace ErsatzTV.Core.Interfaces.Metadata { public interface ILocalStatisticsProvider { - Task RefreshStatistics(string ffprobePath, MediaItem mediaItem); + Task> RefreshStatistics(string ffprobePath, MediaItem mediaItem); } } diff --git a/ErsatzTV.Core/Metadata/LocalFolderScanner.cs b/ErsatzTV.Core/Metadata/LocalFolderScanner.cs index dd29814b7..ad6e80d8b 100644 --- a/ErsatzTV.Core/Metadata/LocalFolderScanner.cs +++ b/ErsatzTV.Core/Metadata/LocalFolderScanner.cs @@ -80,7 +80,15 @@ namespace ErsatzTV.Core.Metadata if (version.DateUpdated < _localFileSystem.GetLastWriteTime(path)) { _logger.LogDebug("Refreshing {Attribute} for {Path}", "Statistics", path); - await _localStatisticsProvider.RefreshStatistics(ffprobePath, mediaItem); + Either refreshResult = + await _localStatisticsProvider.RefreshStatistics(ffprobePath, mediaItem); + refreshResult.IfLeft( + error => + _logger.LogWarning( + "Unable to refresh {Attribute} for media item {Path}. Error: {Error}", + "Statistics", + path, + error.Value)); } return mediaItem; diff --git a/ErsatzTV.Core/Metadata/LocalStatisticsProvider.cs b/ErsatzTV.Core/Metadata/LocalStatisticsProvider.cs index cf4ebce83..1541f6870 100644 --- a/ErsatzTV.Core/Metadata/LocalStatisticsProvider.cs +++ b/ErsatzTV.Core/Metadata/LocalStatisticsProvider.cs @@ -29,7 +29,7 @@ namespace ErsatzTV.Core.Metadata _logger = logger; } - public async Task RefreshStatistics(string ffprobePath, MediaItem mediaItem) + public async Task> RefreshStatistics(string ffprobePath, MediaItem mediaItem) { try { @@ -40,14 +40,20 @@ namespace ErsatzTV.Core.Metadata _ => throw new ArgumentOutOfRangeException(nameof(mediaItem)) }; - FFprobe ffprobe = await GetProbeOutput(ffprobePath, filePath); - MediaVersion version = ProjectToMediaVersion(ffprobe); - return await ApplyVersionUpdate(mediaItem, version, filePath); + Either maybeProbe = await GetProbeOutput(ffprobePath, filePath); + return await maybeProbe.Match( + async ffprobe => + { + MediaVersion version = ProjectToMediaVersion(ffprobe); + await ApplyVersionUpdate(mediaItem, version, filePath); + return Right(Unit.Default); + }, + error => Task.FromResult(Left(error))); } catch (Exception ex) { _logger.LogWarning(ex, "Failed to refresh statistics for media item {Id}", mediaItem.Id); - return false; + return BaseError.New(ex.Message); } } @@ -76,7 +82,7 @@ namespace ErsatzTV.Core.Metadata return await _mediaItemRepository.Update(mediaItem) && durationChange; } - private Task GetProbeOutput(string ffprobePath, string filePath) + private Task> GetProbeOutput(string ffprobePath, string filePath) { var startInfo = new ProcessStartInfo { @@ -101,11 +107,13 @@ namespace ErsatzTV.Core.Metadata }; probe.Start(); - return probe.StandardOutput.ReadToEndAsync().MapAsync( + return probe.StandardOutput.ReadToEndAsync().MapAsync>( async output => { await probe.WaitForExitAsync(); - return JsonConvert.DeserializeObject(output); + return probe.ExitCode == 0 + ? JsonConvert.DeserializeObject(output) + : BaseError.New($"FFprobe at {ffprobePath} exited with code {probe.ExitCode}"); }); }