From 4a7bd5b849bee6caea30213e4e66a81efd6861ca Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 19 Nov 2013 21:47:26 -0800 Subject: [PATCH] Better handling of SAB not returning json to addfile Fixed: Handling of unexpected responses from SABnzbd when adding releases --- src/NzbDrone.Common/Serializer/Json.cs | 12 ++++++ .../Clients/Sabnzbd/SabAddResponse.cs | 5 +++ .../Clients/Sabnzbd/SabCommunicationProxy.cs | 40 ++++++++++++++++--- .../Download/Clients/Sabnzbd/SabJsonError.cs | 2 +- .../Download/Clients/Sabnzbd/SabnzbdClient.cs | 11 +++-- 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/NzbDrone.Common/Serializer/Json.cs b/src/NzbDrone.Common/Serializer/Json.cs index bf54fb250..9a9b0e04b 100644 --- a/src/NzbDrone.Common/Serializer/Json.cs +++ b/src/NzbDrone.Common/Serializer/Json.cs @@ -41,6 +41,18 @@ namespace NzbDrone.Common.Serializer return JsonConvert.DeserializeObject(json, type, SerializerSetting); } + public static T TryDeserialize(string json) where T : new() + { + try + { + return Deserialize(json); + } + catch (JsonReaderException ex) + { + return default(T); + } + } + public static string ToJson(this object obj) { return JsonConvert.SerializeObject(obj, SerializerSetting); diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabAddResponse.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabAddResponse.cs index 83246d75e..040b2b2b4 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabAddResponse.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabAddResponse.cs @@ -6,6 +6,11 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd { public class SabAddResponse { + public SabAddResponse() + { + Ids = new List(); + } + public bool Status { get; set; } [JsonProperty(PropertyName = "nzo_ids")] diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabCommunicationProxy.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabCommunicationProxy.cs index c151d4cf2..7d625b01a 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabCommunicationProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabCommunicationProxy.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using Newtonsoft.Json; using NLog; using NzbDrone.Common.Serializer; using NzbDrone.Core.Configuration; @@ -9,7 +10,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd { public interface ISabCommunicationProxy { - string DownloadNzb(Stream nzb, string name, string category, int priority); + SabAddResponse DownloadNzb(Stream nzb, string name, string category, int priority); void RemoveFrom(string source, string id); string ProcessRequest(IRestRequest restRequest, string action); } @@ -25,14 +26,22 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd _logger = logger; } - public string DownloadNzb(Stream nzb, string title, string category, int priority) + public SabAddResponse DownloadNzb(Stream nzb, string title, string category, int priority) { var request = new RestRequest(Method.POST); var action = String.Format("mode=addfile&cat={0}&priority={1}", category, priority); request.AddFile("name", ReadFully(nzb), title, "application/x-nzb"); - return ProcessRequest(request, action); + var response = Json.TryDeserialize(ProcessRequest(request, action)); + + if (response == null) + { + response = new SabAddResponse(); + response.Status = true; + } + + return response; } public void RemoveFrom(string source, string id) @@ -67,6 +76,8 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd _configService.SabUsername, _configService.SabPassword); + _logger.Trace(url); + return new RestClient(url); } @@ -77,9 +88,28 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd throw new ApplicationException("Unable to connect to SABnzbd, please check your settings"); } - var result = Json.Deserialize(response.Content); + var result = Json.TryDeserialize(response.Content); - if (result.Status != null && result.Status.Equals("false", StringComparison.InvariantCultureIgnoreCase)) + if (result == null) + { + //Handle plain text responses from SAB + result = new SabJsonError(); + + if (response.Content.StartsWith("error", StringComparison.InvariantCultureIgnoreCase)) + { + result.Status = false; + result.Error = response.Content.Replace("error: ", ""); + } + + else + { + result.Status = true; + } + + result.Error = response.Content.Replace("error: ", ""); + } + + if (!result.Status) throw new ApplicationException(result.Error); } diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabJsonError.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabJsonError.cs index 4a8b00045..30fab767c 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabJsonError.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabJsonError.cs @@ -2,7 +2,7 @@ { public class SabJsonError { - public string Status { get; set; } + public bool Status { get; set; } public string Error { get; set; } } } diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdClient.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdClient.cs index 21c3b21f5..f82af3874 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdClient.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdClient.cs @@ -55,11 +55,14 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd using (var nzb = _httpProvider.DownloadStream(url)) { _logger.Info("Adding report [{0}] to the queue.", title); - var response = Json.Deserialize(_sabCommunicationProxy.DownloadNzb(nzb, title, category, priority)); + var response = _sabCommunicationProxy.DownloadNzb(nzb, title, category, priority); - _logger.Debug("Queue Response: [{0}]", response.Status); + if (response != null && response.Ids.Any()) + { + return response.Ids.First(); + } - return response.Ids.First(); + return null; } } @@ -240,7 +243,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd { var result = Json.Deserialize(response); - if (result.Status != null && result.Status.Equals("false", StringComparison.InvariantCultureIgnoreCase)) + if (result.Status) throw new ApplicationException(result.Error); } }