From a117001de673e80abd90d54a34a7c86292b3a649 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 20 May 2023 22:22:04 +0300 Subject: [PATCH] New: Improve validation messages --- src/NzbDrone.Core/Validation/FolderValidator.cs | 4 +++- .../Validation/Paths/FileExistsValidator.cs | 4 +++- .../Validation/Paths/FolderWritableValidator.cs | 5 ++++- .../Validation/Paths/PathExistsValidator.cs | 4 +++- src/NzbDrone.Core/Validation/Paths/PathValidator.cs | 4 +++- .../Validation/Paths/RecycleBinValidator.cs | 6 ++++-- .../Validation/Paths/RootFolderAncestorValidator.cs | 4 +++- .../Validation/Paths/RootFolderValidator.cs | 4 +++- .../Validation/Paths/SeriesAncestorValidator.cs | 4 +++- .../Validation/Paths/SeriesPathValidator.cs | 4 +++- .../Validation/Paths/StartupFolderValidator.cs | 3 ++- .../Validation/Paths/SystemFolderValidator.cs | 3 ++- src/NzbDrone.Core/Validation/UrlValidator.cs | 4 +++- .../Series/SeriesFolderAsRootFolderValidator.cs | 9 +++++---- 14 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/NzbDrone.Core/Validation/FolderValidator.cs b/src/NzbDrone.Core/Validation/FolderValidator.cs index 405fe14bd..99d1bcee8 100644 --- a/src/NzbDrone.Core/Validation/FolderValidator.cs +++ b/src/NzbDrone.Core/Validation/FolderValidator.cs @@ -6,7 +6,7 @@ namespace NzbDrone.Core.Validation { public class FolderValidator : PropertyValidator { - protected override string GetDefaultMessageTemplate() => "Invalid Path"; + protected override string GetDefaultMessageTemplate() => "Invalid Path: '{path}'"; protected override bool IsValid(PropertyValidatorContext context) { @@ -15,6 +15,8 @@ namespace NzbDrone.Core.Validation return false; } + context.MessageFormatter.AppendArgument("path", context.PropertyValue.ToString()); + return context.PropertyValue.ToString().IsPathValid(PathValidationType.CurrentOs); } } diff --git a/src/NzbDrone.Core/Validation/Paths/FileExistsValidator.cs b/src/NzbDrone.Core/Validation/Paths/FileExistsValidator.cs index 02e2aef81..5393ce57b 100644 --- a/src/NzbDrone.Core/Validation/Paths/FileExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/FileExistsValidator.cs @@ -12,7 +12,7 @@ namespace NzbDrone.Core.Validation.Paths _diskProvider = diskProvider; } - protected override string GetDefaultMessageTemplate() => "File does not exist"; + protected override string GetDefaultMessageTemplate() => "File '{file}' does not exist"; protected override bool IsValid(PropertyValidatorContext context) { @@ -21,6 +21,8 @@ namespace NzbDrone.Core.Validation.Paths return false; } + context.MessageFormatter.AppendArgument("file", context.PropertyValue.ToString()); + return _diskProvider.FileExists(context.PropertyValue.ToString()); } } diff --git a/src/NzbDrone.Core/Validation/Paths/FolderWritableValidator.cs b/src/NzbDrone.Core/Validation/Paths/FolderWritableValidator.cs index 6838b3ea6..c9bfdbf58 100644 --- a/src/NzbDrone.Core/Validation/Paths/FolderWritableValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/FolderWritableValidator.cs @@ -13,7 +13,7 @@ namespace NzbDrone.Core.Validation.Paths _diskProvider = diskProvider; } - protected override string GetDefaultMessageTemplate() => $"Folder is not writable by user {Environment.UserName}"; + protected override string GetDefaultMessageTemplate() => "Folder '{path}' is not writable by user '{user}'"; protected override bool IsValid(PropertyValidatorContext context) { @@ -22,6 +22,9 @@ namespace NzbDrone.Core.Validation.Paths return false; } + context.MessageFormatter.AppendArgument("path", context.PropertyValue.ToString()); + context.MessageFormatter.AppendArgument("user", Environment.UserName); + return _diskProvider.FolderWritable(context.PropertyValue.ToString()); } } diff --git a/src/NzbDrone.Core/Validation/Paths/PathExistsValidator.cs b/src/NzbDrone.Core/Validation/Paths/PathExistsValidator.cs index 91493482f..fbf7b2690 100644 --- a/src/NzbDrone.Core/Validation/Paths/PathExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/PathExistsValidator.cs @@ -12,7 +12,7 @@ namespace NzbDrone.Core.Validation.Paths _diskProvider = diskProvider; } - protected override string GetDefaultMessageTemplate() => "Path does not exist"; + protected override string GetDefaultMessageTemplate() => "Path '{path}' does not exist"; protected override bool IsValid(PropertyValidatorContext context) { @@ -21,6 +21,8 @@ namespace NzbDrone.Core.Validation.Paths return false; } + context.MessageFormatter.AppendArgument("path", context.PropertyValue.ToString()); + return _diskProvider.FolderExists(context.PropertyValue.ToString()); } } diff --git a/src/NzbDrone.Core/Validation/Paths/PathValidator.cs b/src/NzbDrone.Core/Validation/Paths/PathValidator.cs index 831d0e2a7..13da8a937 100644 --- a/src/NzbDrone.Core/Validation/Paths/PathValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/PathValidator.cs @@ -15,7 +15,7 @@ namespace NzbDrone.Core.Validation.Paths public class PathValidator : PropertyValidator { - protected override string GetDefaultMessageTemplate() => "Invalid Path"; + protected override string GetDefaultMessageTemplate() => "Invalid Path: '{path}'"; protected override bool IsValid(PropertyValidatorContext context) { @@ -24,6 +24,8 @@ namespace NzbDrone.Core.Validation.Paths return false; } + context.MessageFormatter.AppendArgument("path", context.PropertyValue.ToString()); + return context.PropertyValue.ToString().IsPathValid(PathValidationType.CurrentOs); } } diff --git a/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs b/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs index 1299b72ac..0c30f7bb7 100644 --- a/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs @@ -13,18 +13,20 @@ namespace NzbDrone.Core.Validation.Paths _configService = configService; } - protected override string GetDefaultMessageTemplate() => "Path is {relationship} configured recycle bin folder"; + protected override string GetDefaultMessageTemplate() => "Path '{path}' is {relationship} configured recycle bin folder"; protected override bool IsValid(PropertyValidatorContext context) { var recycleBin = _configService.RecycleBin; - var folder = context.PropertyValue.ToString(); if (context.PropertyValue == null || recycleBin.IsNullOrWhiteSpace()) { return true; } + var folder = context.PropertyValue.ToString(); + context.MessageFormatter.AppendArgument("path", folder); + if (recycleBin.PathEquals(folder)) { context.MessageFormatter.AppendArgument("relationship", "set to"); diff --git a/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs b/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs index 1b7dd0bfa..c7d9db864 100644 --- a/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs @@ -14,7 +14,7 @@ namespace NzbDrone.Core.Validation.Paths _rootFolderService = rootFolderService; } - protected override string GetDefaultMessageTemplate() => "Path is an ancestor of an existing root folder"; + protected override string GetDefaultMessageTemplate() => "Path '{path}' is an ancestor of an existing root folder"; protected override bool IsValid(PropertyValidatorContext context) { @@ -23,6 +23,8 @@ namespace NzbDrone.Core.Validation.Paths return true; } + context.MessageFormatter.AppendArgument("path", context.PropertyValue.ToString()); + return !_rootFolderService.All().Any(s => context.PropertyValue.ToString().IsParentPath(s.Path)); } } diff --git a/src/NzbDrone.Core/Validation/Paths/RootFolderValidator.cs b/src/NzbDrone.Core/Validation/Paths/RootFolderValidator.cs index 7ceffdd7a..7f3db8ed3 100644 --- a/src/NzbDrone.Core/Validation/Paths/RootFolderValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/RootFolderValidator.cs @@ -13,7 +13,7 @@ namespace NzbDrone.Core.Validation.Paths _rootFolderService = rootFolderService; } - protected override string GetDefaultMessageTemplate() => "Path is already configured as a root folder"; + protected override string GetDefaultMessageTemplate() => "Path '{path}' is already configured as a root folder"; protected override bool IsValid(PropertyValidatorContext context) { @@ -22,6 +22,8 @@ namespace NzbDrone.Core.Validation.Paths return true; } + context.MessageFormatter.AppendArgument("path", context.PropertyValue.ToString()); + return !_rootFolderService.All().Exists(r => r.Path.PathEquals(context.PropertyValue.ToString())); } } diff --git a/src/NzbDrone.Core/Validation/Paths/SeriesAncestorValidator.cs b/src/NzbDrone.Core/Validation/Paths/SeriesAncestorValidator.cs index 401246d47..cf2c8c117 100644 --- a/src/NzbDrone.Core/Validation/Paths/SeriesAncestorValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/SeriesAncestorValidator.cs @@ -14,7 +14,7 @@ namespace NzbDrone.Core.Validation.Paths _seriesService = seriesService; } - protected override string GetDefaultMessageTemplate() => "Path is an ancestor of an existing series"; + protected override string GetDefaultMessageTemplate() => "Path '{path}' is an ancestor of an existing series"; protected override bool IsValid(PropertyValidatorContext context) { @@ -23,6 +23,8 @@ namespace NzbDrone.Core.Validation.Paths return true; } + context.MessageFormatter.AppendArgument("path", context.PropertyValue.ToString()); + return !_seriesService.GetAllSeriesPaths().Any(s => context.PropertyValue.ToString().IsParentPath(s.Value)); } } diff --git a/src/NzbDrone.Core/Validation/Paths/SeriesPathValidator.cs b/src/NzbDrone.Core/Validation/Paths/SeriesPathValidator.cs index 5b1ff9373..80ce3541a 100644 --- a/src/NzbDrone.Core/Validation/Paths/SeriesPathValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/SeriesPathValidator.cs @@ -13,7 +13,7 @@ namespace NzbDrone.Core.Validation.Paths _seriesService = seriesService; } - protected override string GetDefaultMessageTemplate() => "Path is already configured for another series"; + protected override string GetDefaultMessageTemplate() => "Path '{path}' is already configured for another series"; protected override bool IsValid(PropertyValidatorContext context) { @@ -22,6 +22,8 @@ namespace NzbDrone.Core.Validation.Paths return true; } + context.MessageFormatter.AppendArgument("path", context.PropertyValue.ToString()); + dynamic instance = context.ParentContext.InstanceToValidate; var instanceId = (int)instance.Id; diff --git a/src/NzbDrone.Core/Validation/Paths/StartupFolderValidator.cs b/src/NzbDrone.Core/Validation/Paths/StartupFolderValidator.cs index 0243923f1..bba19907f 100644 --- a/src/NzbDrone.Core/Validation/Paths/StartupFolderValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/StartupFolderValidator.cs @@ -13,7 +13,7 @@ namespace NzbDrone.Core.Validation.Paths _appFolderInfo = appFolderInfo; } - protected override string GetDefaultMessageTemplate() => "Path cannot be {relationship} the start up folder"; + protected override string GetDefaultMessageTemplate() => "Path '{path}' cannot be {relationship} the start up folder"; protected override bool IsValid(PropertyValidatorContext context) { @@ -24,6 +24,7 @@ namespace NzbDrone.Core.Validation.Paths var startupFolder = _appFolderInfo.StartUpFolder; var folder = context.PropertyValue.ToString(); + context.MessageFormatter.AppendArgument("path", folder); if (startupFolder.PathEquals(folder)) { diff --git a/src/NzbDrone.Core/Validation/Paths/SystemFolderValidator.cs b/src/NzbDrone.Core/Validation/Paths/SystemFolderValidator.cs index 6b891394e..8483bd8c4 100644 --- a/src/NzbDrone.Core/Validation/Paths/SystemFolderValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/SystemFolderValidator.cs @@ -6,11 +6,12 @@ namespace NzbDrone.Core.Validation.Paths { public class SystemFolderValidator : PropertyValidator { - protected override string GetDefaultMessageTemplate() => "Is {relationship} system folder {systemFolder}"; + protected override string GetDefaultMessageTemplate() => "Path '{path}' is {relationship} system folder {systemFolder}"; protected override bool IsValid(PropertyValidatorContext context) { var folder = context.PropertyValue.ToString(); + context.MessageFormatter.AppendArgument("path", folder); foreach (var systemFolder in SystemFolders.GetSystemFolders()) { diff --git a/src/NzbDrone.Core/Validation/UrlValidator.cs b/src/NzbDrone.Core/Validation/UrlValidator.cs index 8588b4848..26cb06d74 100644 --- a/src/NzbDrone.Core/Validation/UrlValidator.cs +++ b/src/NzbDrone.Core/Validation/UrlValidator.cs @@ -14,7 +14,7 @@ namespace NzbDrone.Core.Validation public class UrlValidator : PropertyValidator { - protected override string GetDefaultMessageTemplate() => "Invalid Url"; + protected override string GetDefaultMessageTemplate() => "Invalid Url: '{url}'"; protected override bool IsValid(PropertyValidatorContext context) { @@ -23,6 +23,8 @@ namespace NzbDrone.Core.Validation return false; } + context.MessageFormatter.AppendArgument("url", context.PropertyValue.ToString()); + return context.PropertyValue.ToString().IsValidUrl(); } } diff --git a/src/Sonarr.Api.V3/Series/SeriesFolderAsRootFolderValidator.cs b/src/Sonarr.Api.V3/Series/SeriesFolderAsRootFolderValidator.cs index 383d1d540..769890fed 100644 --- a/src/Sonarr.Api.V3/Series/SeriesFolderAsRootFolderValidator.cs +++ b/src/Sonarr.Api.V3/Series/SeriesFolderAsRootFolderValidator.cs @@ -15,7 +15,7 @@ namespace Sonarr.Api.V3.Series _fileNameBuilder = fileNameBuilder; } - protected override string GetDefaultMessageTemplate() => "Root folder path contains series folder"; + protected override string GetDefaultMessageTemplate() => "Root folder path '{rootFolderPath}' contains series folder '{seriesFolder}'"; protected override bool IsValid(PropertyValidatorContext context) { @@ -24,9 +24,7 @@ namespace Sonarr.Api.V3.Series return true; } - var seriesResource = context.InstanceToValidate as SeriesResource; - - if (seriesResource == null) + if (context.InstanceToValidate is not SeriesResource seriesResource) { return true; } @@ -42,6 +40,9 @@ namespace Sonarr.Api.V3.Series var series = seriesResource.ToModel(); var seriesFolder = _fileNameBuilder.GetSeriesFolder(series); + context.MessageFormatter.AppendArgument("rootFolderPath", rootFolderPath); + context.MessageFormatter.AppendArgument("seriesFolder", seriesFolder); + if (seriesFolder == rootFolder) { return false;