diff --git a/NzbDrone.Api/ErrorManagement/ApiException.cs b/NzbDrone.Api/ErrorManagement/ApiException.cs index 0d5842d19..2a9f2678f 100644 --- a/NzbDrone.Api/ErrorManagement/ApiException.cs +++ b/NzbDrone.Api/ErrorManagement/ApiException.cs @@ -9,7 +9,6 @@ namespace NzbDrone.Api.ErrorManagement { public object Content { get; private set; } - public HttpStatusCode StatusCode { get; private set; } protected ApiException(HttpStatusCode statusCode, object content = null) diff --git a/NzbDrone.Api/ErrorManagement/NzbDroneErrorPipeline.cs b/NzbDrone.Api/ErrorManagement/NzbDroneErrorPipeline.cs index 9db64b37d..2a2d0b834 100644 --- a/NzbDrone.Api/ErrorManagement/NzbDroneErrorPipeline.cs +++ b/NzbDrone.Api/ErrorManagement/NzbDroneErrorPipeline.cs @@ -3,6 +3,7 @@ using FluentValidation; using NLog; using Nancy; using NzbDrone.Api.Extensions; +using NzbDrone.Common.Exceptions; using HttpStatusCode = Nancy.HttpStatusCode; namespace NzbDrone.Api.ErrorManagement @@ -35,9 +36,20 @@ namespace NzbDrone.Api.ErrorManagement return validationException.Errors.AsResponse(HttpStatusCode.BadRequest); } + var clientException = exception as NzbDroneClientException; + + if (clientException != null) + { + return new ErrorModel + { + Message = exception.Message, + Description = exception.ToString() + }.AsResponse((HttpStatusCode)clientException.StatusCode); + } + _logger.FatalException("Request Failed", exception); - return new ErrorModel() + return new ErrorModel { Message = exception.Message, Description = exception.ToString() diff --git a/NzbDrone.Common/Exceptions/NzbDroneClientException.cs b/NzbDrone.Common/Exceptions/NzbDroneClientException.cs new file mode 100644 index 000000000..3f5bc8927 --- /dev/null +++ b/NzbDrone.Common/Exceptions/NzbDroneClientException.cs @@ -0,0 +1,20 @@ +using System.Net; + +namespace NzbDrone.Common.Exceptions +{ + public class NzbDroneClientException : NzbDroneException + { + public HttpStatusCode StatusCode { get; private set; } + + public NzbDroneClientException(HttpStatusCode statusCode, string message, params object[] args) : base(message, args) + { + StatusCode = statusCode; + } + + public NzbDroneClientException(HttpStatusCode statusCode, string message) + : base(message) + { + StatusCode = statusCode; + } + } +} diff --git a/NzbDrone.Common/Exceptions/NzbDroneException.cs b/NzbDrone.Common/Exceptions/NzbDroneException.cs index 09b431fc6..b67c32515 100644 --- a/NzbDrone.Common/Exceptions/NzbDroneException.cs +++ b/NzbDrone.Common/Exceptions/NzbDroneException.cs @@ -2,8 +2,6 @@ namespace NzbDrone.Common.Exceptions { - - public abstract class NzbDroneException : ApplicationException { protected NzbDroneException(string message, params object[] args) diff --git a/NzbDrone.Common/NzbDrone.Common.csproj b/NzbDrone.Common/NzbDrone.Common.csproj index 6a4006315..e3fb239c0 100644 --- a/NzbDrone.Common/NzbDrone.Common.csproj +++ b/NzbDrone.Common/NzbDrone.Common.csproj @@ -88,6 +88,7 @@ + diff --git a/NzbDrone.Core/MetadataSource/Trakt/TraktCommunicationException.cs b/NzbDrone.Core/MetadataSource/Trakt/TraktCommunicationException.cs deleted file mode 100644 index d09dad66c..000000000 --- a/NzbDrone.Core/MetadataSource/Trakt/TraktCommunicationException.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace NzbDrone.Core.MetadataSource.Trakt -{ - public class TraktCommunicationException : Exception - { - public TraktCommunicationException(string message, Exception innerException) : base(message, innerException) - { - } - } -} diff --git a/NzbDrone.Core/MetadataSource/Trakt/TraktException.cs b/NzbDrone.Core/MetadataSource/Trakt/TraktException.cs new file mode 100644 index 000000000..edafb1ca3 --- /dev/null +++ b/NzbDrone.Core/MetadataSource/Trakt/TraktException.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using NzbDrone.Common.Exceptions; + +namespace NzbDrone.Core.MetadataSource.Trakt +{ + public class TraktException : NzbDroneClientException + { + public TraktException(string message) : base(HttpStatusCode.ServiceUnavailable, message) + { + } + + public TraktException(string message, params object[] args) : base(HttpStatusCode.ServiceUnavailable, message, args) + { + } + } +} diff --git a/NzbDrone.Core/MetadataSource/TraktProxy.cs b/NzbDrone.Core/MetadataSource/TraktProxy.cs index 065b3371e..f488a4f65 100644 --- a/NzbDrone.Core/MetadataSource/TraktProxy.cs +++ b/NzbDrone.Core/MetadataSource/TraktProxy.cs @@ -2,7 +2,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net; using System.Text.RegularExpressions; +using NLog; using NzbDrone.Common; using NzbDrone.Core.MediaCover; using NzbDrone.Core.MetadataSource.Trakt; @@ -15,26 +17,33 @@ namespace NzbDrone.Core.MetadataSource { public class TraktProxy : ISearchForNewSeries, IProvideSeriesInfo { - public List SearchForNewSeries(string title) - { - var client = BuildClient("search", "shows"); - var restRequest = new RestRequest(GetSearchTerm(title)); - var response = client.ExecuteAndValidate>(restRequest); + private readonly Logger _logger; + private static readonly Regex InvalidSearchCharRegex = new Regex(@"[^a-zA-Z0-9\s-\.]", RegexOptions.Compiled); - return response.Select(MapSearchSeries).ToList(); + public TraktProxy(Logger logger) + { + _logger = logger; } - - private static readonly Regex InvalidSearchCharRegex = new Regex(@"[^a-zA-Z0-9\s-\.]", RegexOptions.Compiled); - - private static string GetSearchTerm(string phrase) + public List SearchForNewSeries(string title) { - phrase = phrase.RemoveAccent().ToLower(); - phrase = phrase.Replace("&", "and"); - phrase = InvalidSearchCharRegex.Replace(phrase, string.Empty); - phrase = phrase.CleanSpaces().Replace(" ", "+"); + try + { + var client = BuildClient("search", "shows"); + var restRequest = new RestRequest(GetSearchTerm(title)); + var response = client.ExecuteAndValidate>(restRequest); - return phrase; + return response.Select(MapSearchSeries).ToList(); + } + catch (WebException ex) + { + throw new TraktException("Search for '{0}' failed. Unable to communicate with Trakt.", title); + } + catch (Exception ex) + { + _logger.WarnException(ex.Message, ex); + throw new TraktException("Search for '{0}' failed. Invalid response received from Trakt.", title); + } } public Tuple> GetSeriesInfo(int tvDbSeriesId) @@ -43,7 +52,6 @@ namespace NzbDrone.Core.MetadataSource var restRequest = new RestRequest(tvDbSeriesId.ToString() + "/extended"); var response = client.ExecuteAndValidate(restRequest); - var episodes = response.seasons.SelectMany(c => c.episodes).Select(MapEpisode).ToList(); var series = MapSeries(response); @@ -164,6 +172,14 @@ namespace NzbDrone.Core.MetadataSource return match.Captures[0].Value; } + private static string GetSearchTerm(string phrase) + { + phrase = phrase.RemoveAccent().ToLower(); + phrase = phrase.Replace("&", "and"); + phrase = InvalidSearchCharRegex.Replace(phrase, string.Empty); + phrase = phrase.CleanSpaces().Replace(" ", "+"); + return phrase; + } } } \ No newline at end of file diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index d15de6be0..10a35bc97 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -223,6 +223,7 @@ + @@ -251,7 +252,6 @@ - diff --git a/UI/Instrumentation/ErrorHandler.js b/UI/Instrumentation/ErrorHandler.js index 589723771..7909dc5fb 100644 --- a/UI/Instrumentation/ErrorHandler.js +++ b/UI/Instrumentation/ErrorHandler.js @@ -73,8 +73,14 @@ return false; } + else if (xmlHttpRequest.status === 503) { + message.message = xmlHttpRequest.responseJSON.message; + } - message.message = '[{0}] {1} : {2}'.format(ajaxOptions.type, xmlHttpRequest.statusText, ajaxOptions.url); + else + { + message.message = '[{0}] {1} : {2}'.format(ajaxOptions.type, xmlHttpRequest.statusText, ajaxOptions.url); + } window.Messenger().post(message); return false;