fix(sonarr): Skip over invalid release profile JSON files

Fixes #87
pull/92/head
Robert Dailey 2 years ago
parent 5ad8db1294
commit 68f89f6cb5

@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Do not exit when a YAML config has no sonarr or radarr section.
- Sonarr: Invalid release profile JSON files no longer cause the program to exit. Instead, it just
skips them and prints a warning to the user. (#87)
## [2.2.0] - 2022-06-03

@ -0,0 +1,17 @@
using System.IO.Abstractions.TestingHelpers;
using Newtonsoft.Json;
namespace TestLibrary;
public static class MockData
{
public static MockFileData FromJson(object json)
{
return new MockFileData(JsonConvert.SerializeObject(json));
}
public static MockFileData FromString(string data)
{
return new MockFileData(data);
}
}

@ -1,9 +1,12 @@
using System.IO.Abstractions;
using System.IO.Abstractions.Extensions;
using System.IO.Abstractions.TestingHelpers;
using AutoFixture.NUnit3;
using FluentAssertions;
using Newtonsoft.Json;
using NSubstitute;
using NUnit.Framework;
using TestLibrary;
using TestLibrary.AutoFixture;
using TrashLib.Sonarr.ReleaseProfile;
using TrashLib.Sonarr.ReleaseProfile.Guide;
@ -48,4 +51,35 @@ public class LocalRepoReleaseProfileJsonParserTest
mockData2
});
}
[Test, AutoMockData]
public void Json_exceptions_do_not_interrupt_parsing_other_files(
[Frozen(Matching.ImplementedInterfaces)] MockFileSystem fs,
[Frozen] IAppPaths paths,
LocalRepoReleaseProfileJsonParser sut)
{
paths.RepoDirectory.Returns("");
var rootPath = fs.CurrentDirectory()
.SubDirectory("docs")
.SubDirectory("json")
.SubDirectory("sonarr");
var badData = "# comment";
var goodData = new ReleaseProfileData
{
Name = "name",
TrashId = "123",
Required = new TermData[]
{
new() {Term = "abc"}
}
};
fs.AddFile(rootPath.File("0_bad_data.json").FullName, MockData.FromString(badData));
fs.AddFile(rootPath.File("1_good_data.json").FullName, MockData.FromJson(goodData));
var results = sut.GetReleaseProfileData();
results.Should().BeEquivalentTo(new[] {goodData});
}
}

@ -3,35 +3,61 @@ using Common.Extensions;
using Common.FluentValidation;
using MoreLinq;
using Newtonsoft.Json;
using Serilog;
namespace TrashLib.Sonarr.ReleaseProfile.Guide;
public class LocalRepoReleaseProfileJsonParser : ISonarrGuideService
{
private readonly IFileSystem _fileSystem;
private readonly IFileSystem _fs;
private readonly IAppPaths _paths;
private readonly ILogger _log;
private readonly Lazy<IEnumerable<ReleaseProfileData>> _data;
public LocalRepoReleaseProfileJsonParser(IFileSystem fileSystem, IAppPaths paths)
public LocalRepoReleaseProfileJsonParser(IFileSystem fs, IAppPaths paths, ILogger log)
{
_fileSystem = fileSystem;
_fs = fs;
_paths = paths;
_log = log;
_data = new Lazy<IEnumerable<ReleaseProfileData>>(GetReleaseProfileDataImpl);
}
private IEnumerable<ReleaseProfileData> GetReleaseProfileDataImpl()
{
var converter = new TermDataConverter();
var jsonDir = _fileSystem.Path.Combine(_paths.RepoDirectory, "docs/json/sonarr");
var tasks = _fileSystem.Directory.GetFiles(jsonDir, "*.json")
.Select(async f =>
{
var json = await _fileSystem.File.ReadAllTextAsync(f);
return JsonConvert.DeserializeObject<ReleaseProfileData>(json, converter);
});
var jsonDir = _fs.Path.Combine(_paths.RepoDirectory, "docs/json/sonarr");
var tasks = _fs.Directory.GetFiles(jsonDir, "*.json")
.Select(f => LoadAndParseFile(f, converter));
return Task.WhenAll(tasks).Result
.Choose(x => x is not null ? (true, x) : default); // Make non-nullable type
// Make non-nullable type and filter out null values
.Choose(x => x is not null ? (true, x) : default);
}
private async Task<ReleaseProfileData?> LoadAndParseFile(string file, params JsonConverter[] converters)
{
try
{
var json = await _fs.File.ReadAllTextAsync(file);
return JsonConvert.DeserializeObject<ReleaseProfileData>(json, converters);
}
catch (JsonException e)
{
HandleJsonException(e, file);
}
catch (AggregateException ae) when (ae.InnerException is JsonException e)
{
HandleJsonException(e, file);
}
return null;
}
private void HandleJsonException(JsonException exception, string file)
{
_log.Warning(exception,
"Failed to parse Sonarr JSON file (This likely indicates a bug that should be " +
"reported in the TRaSH repo): {File}", _fs.Path.GetFileName(file));
}
public ReleaseProfileData? GetUnfilteredProfileById(string trashId)

Loading…
Cancel
Save