parent
cd6eda4055
commit
3840f9c5ab
@ -1,21 +0,0 @@
|
|||||||
using YamlDotNet.Core;
|
|
||||||
|
|
||||||
namespace Recyclarr.TrashLib.Config.Parsing;
|
|
||||||
|
|
||||||
public static class ConfigDeprecations
|
|
||||||
{
|
|
||||||
public static string? GetContextualErrorFromException(YamlException e)
|
|
||||||
{
|
|
||||||
if (e.Message.Contains("Expected 'MappingStart', got 'SequenceStart'"))
|
|
||||||
{
|
|
||||||
return "Found array-style list of instances instead of named-style. " +
|
|
||||||
"Array-style lists of Sonarr/Radarr instances are not supported. " +
|
|
||||||
"See: https://recyclarr.dev/wiki/upgrade-guide/v5.0/#instances-must-now-be-named";
|
|
||||||
}
|
|
||||||
|
|
||||||
// "DEPRECATION: Support for using `reset_unmatched_scores` under `custom_formats.quality_profiles` " +
|
|
||||||
// "will be removed in a future release. Move it to the top level `quality_profiles` instead"
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,12 @@
|
|||||||
|
using Recyclarr.TrashLib.Config.Yaml;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
|
namespace Recyclarr.TrashLib.Config.Parsing.ErrorHandling;
|
||||||
|
|
||||||
|
public class ConfigFeatureRemovalBehavior : IYamlBehavior
|
||||||
|
{
|
||||||
|
public void Setup(DeserializerBuilder builder)
|
||||||
|
{
|
||||||
|
builder.WithNodeTypeResolver(new FeatureRemovalChecker());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
using YamlDotNet.Core;
|
||||||
|
|
||||||
|
namespace Recyclarr.TrashLib.Config.Parsing.ErrorHandling;
|
||||||
|
|
||||||
|
public static class ContextualMessages
|
||||||
|
{
|
||||||
|
public static string? GetContextualErrorFromException(YamlException e)
|
||||||
|
{
|
||||||
|
if (e.Message.Contains(
|
||||||
|
"Property 'reset_unmatched_scores' not found on type " +
|
||||||
|
$"'{typeof(QualityScoreConfigYaml).FullName}'"))
|
||||||
|
{
|
||||||
|
return
|
||||||
|
"Usage of 'reset_unmatched_scores' inside 'quality_profiles' under 'custom_formats' is no " +
|
||||||
|
"longer supported. Use the root-level 'quality_profiles' instead. " +
|
||||||
|
"See: https://recyclarr.dev/wiki/upgrade-guide/v5.0#reset-unmatched-scores";
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
using YamlDotNet.Core.Events;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
|
namespace Recyclarr.TrashLib.Config.Parsing.ErrorHandling;
|
||||||
|
|
||||||
|
// Note: Backward breaking changes involving node removals cannot be handled here, since that will cause exceptions
|
||||||
|
// before the Node Type Resolver gets invoked. Those are handled reactively by inspecting the YamlException object
|
||||||
|
// passed to the ContextualMessages static class.
|
||||||
|
public sealed class FeatureRemovalChecker : INodeTypeResolver
|
||||||
|
{
|
||||||
|
public bool Resolve(NodeEvent? nodeEvent, ref Type currentType)
|
||||||
|
{
|
||||||
|
if (IsDictionaryOfType(currentType, typeof(RadarrConfigYaml), typeof(SonarrConfigYaml)) &&
|
||||||
|
nodeEvent is SequenceStart)
|
||||||
|
{
|
||||||
|
throw new FeatureRemovalException(
|
||||||
|
"Found array-style list of instances instead of named-style. " +
|
||||||
|
"Array-style lists of Sonarr/Radarr instances are not supported.",
|
||||||
|
"https://recyclarr.dev/wiki/upgrade-guide/v5.0/#instances-must-now-be-named");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsDictionaryOfType(Type dictType, params Type[] valueTypes)
|
||||||
|
{
|
||||||
|
if (!dictType.IsGenericType || dictType.GetGenericTypeDefinition() != typeof(IReadOnlyDictionary<,>))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return valueTypes.Contains(dictType.GenericTypeArguments[1]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
using System.Runtime.Serialization;
|
||||||
|
|
||||||
|
namespace Recyclarr.TrashLib.Config.Parsing.ErrorHandling;
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class FeatureRemovalException : Exception
|
||||||
|
{
|
||||||
|
protected FeatureRemovalException(SerializationInfo info, StreamingContext context)
|
||||||
|
: base(info, context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public FeatureRemovalException(string message, string docLink)
|
||||||
|
: base($"{message} See: {docLink}")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
namespace Recyclarr.TrashLib.Config.Parsing;
|
namespace Recyclarr.TrashLib.Config.Parsing.ErrorHandling;
|
||||||
|
|
||||||
public class NoConfigurationFilesException : Exception
|
public class NoConfigurationFilesException : Exception
|
||||||
{
|
{
|
@ -0,0 +1,29 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using YamlDotNet.Core;
|
||||||
|
using YamlDotNet.Core.Events;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
|
namespace Recyclarr.TrashLib.Config.Parsing.ErrorHandling;
|
||||||
|
|
||||||
|
public sealed class SyntaxErrorHelper : INodeTypeResolver
|
||||||
|
{
|
||||||
|
private static readonly string[] CollectionKeywords = {"Collection", "List"};
|
||||||
|
|
||||||
|
public bool Resolve(NodeEvent? nodeEvent, ref Type currentType)
|
||||||
|
{
|
||||||
|
CheckSequenceAssignedToNonSequence(nodeEvent, currentType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the user tries to specify an array as the value for a node type that is not a list type, then we provide our
|
||||||
|
// own exception type. The default error message that YamlDotNet would output doesn't make much sense to users: It
|
||||||
|
// just says "no node type resolver could resolve the type", or something along those lines -- which isn't helpful!
|
||||||
|
private static void CheckSequenceAssignedToNonSequence(ParsingEvent? nodeEvent, MemberInfo currentType)
|
||||||
|
{
|
||||||
|
if (nodeEvent is SequenceStart && !CollectionKeywords.Any(x => currentType.Name.Contains(x)))
|
||||||
|
{
|
||||||
|
throw new YamlException(nodeEvent.Start, nodeEvent.End,
|
||||||
|
$"A list/array/sequence is not allowed for {currentType.Name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue