diff --git a/src/Lidarr.Http/ErrorManagement/LidarrErrorPipeline.cs b/src/Lidarr.Http/ErrorManagement/LidarrErrorPipeline.cs index 64efe250e..e166559ef 100644 --- a/src/Lidarr.Http/ErrorManagement/LidarrErrorPipeline.cs +++ b/src/Lidarr.Http/ErrorManagement/LidarrErrorPipeline.cs @@ -24,26 +24,20 @@ namespace Lidarr.Http.ErrorManagement { _logger.Trace("Handling Exception"); - var apiException = exception as ApiException; - - if (apiException != null) + if (exception is ApiException apiException) { _logger.Warn(apiException, "API Error"); return apiException.ToErrorResponse(context); } - var validationException = exception as ValidationException; - - if (validationException != null) + if (exception is ValidationException validationException) { _logger.Warn("Invalid request {0}", validationException.Message); return validationException.Errors.AsResponse(context, HttpStatusCode.BadRequest); } - var clientException = exception as NzbDroneClientException; - - if (clientException != null) + if (exception is NzbDroneClientException clientException) { return new ErrorModel { @@ -52,9 +46,25 @@ namespace Lidarr.Http.ErrorManagement }.AsResponse(context, (HttpStatusCode)clientException.StatusCode); } - var sqLiteException = exception as SQLiteException; + if (exception is ModelNotFoundException notFoundException) + { + return new ErrorModel + { + Message = exception.Message, + Description = exception.ToString() + }.AsResponse(context, HttpStatusCode.NotFound); + } + + if (exception is ModelConflictException conflictException) + { + return new ErrorModel + { + Message = exception.Message, + Description = exception.ToString() + }.AsResponse(context, HttpStatusCode.Conflict); + } - if (sqLiteException != null) + if (exception is SQLiteException sqLiteException) { if (context.Request.Method == "PUT" || context.Request.Method == "POST") { diff --git a/src/NzbDrone.Core/Datastore/ModelConflictException.cs b/src/NzbDrone.Core/Datastore/ModelConflictException.cs new file mode 100644 index 000000000..66c7f94ff --- /dev/null +++ b/src/NzbDrone.Core/Datastore/ModelConflictException.cs @@ -0,0 +1,20 @@ +using System; +using NzbDrone.Common.Exceptions; + +namespace NzbDrone.Core.Datastore +{ + public class ModelConflictException : NzbDroneException + { + public ModelConflictException(Type modelType, int modelId) + : base("{0} with ID {1} cannot be modified", modelType.Name, modelId) + { + + } + + public ModelConflictException(Type modelType, int modelId, string message) + : base("{0} with ID {1} {2}", modelType.Name, modelId, message) + { + + } + } +} \ No newline at end of file diff --git a/src/NzbDrone.Core/Tags/TagDetails.cs b/src/NzbDrone.Core/Tags/TagDetails.cs index ce433d1c5..20d6c9ce3 100644 --- a/src/NzbDrone.Core/Tags/TagDetails.cs +++ b/src/NzbDrone.Core/Tags/TagDetails.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using NzbDrone.Core.Datastore; namespace NzbDrone.Core.Tags @@ -11,5 +12,13 @@ namespace NzbDrone.Core.Tags public List RestrictionIds { get; set; } public List DelayProfileIds { get; set; } public List ImportListIds { get; set; } + + public bool InUse + { + get + { + return (ArtistIds.Any() || NotificationIds.Any() || RestrictionIds.Any() || DelayProfileIds.Any() || ImportListIds.Any()); + } + } } } diff --git a/src/NzbDrone.Core/Tags/TagService.cs b/src/NzbDrone.Core/Tags/TagService.cs index ce5335cf3..85b966fc4 100644 --- a/src/NzbDrone.Core/Tags/TagService.cs +++ b/src/NzbDrone.Core/Tags/TagService.cs @@ -1,6 +1,8 @@ +using System; using System.Collections.Generic; using System.Linq; using NzbDrone.Core.ImportLists; +using NzbDrone.Core.Datastore; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Notifications; using NzbDrone.Core.Profiles.Delay; @@ -149,6 +151,12 @@ namespace NzbDrone.Core.Tags public void Delete(int tagId) { + var details = Details(tagId); + if (details.InUse) + { + throw new ModelConflictException(typeof(Tag), tagId, $"'{details.Label}' cannot be deleted since it's still in use"); + } + _repo.Delete(tagId); _eventAggregator.PublishEvent(new TagsUpdatedEvent()); }