From adcf01da3d9647e9a768dd732ab31182a4b3b4b3 Mon Sep 17 00:00:00 2001 From: Tobias Klika Date: Sat, 1 Feb 2014 12:21:06 +0100 Subject: [PATCH] response validation; GetMonitors works now --- UptimeSharp.Tests/MonitorsTest.cs | 11 +-- UptimeSharp/Components/Alert.cs | 4 +- UptimeSharp/Components/Monitor.cs | 8 +- UptimeSharp/Models/Response/AlertResponse.cs | 2 +- .../Models/Response/DefaultResponse.cs | 2 +- UptimeSharp/Models/Response/IResponse.cs | 10 +++ .../Response/{ResponseBase.cs => Response.cs} | 8 +- .../Models/Response/RetrieveResponse.cs | 8 +- UptimeSharp/UptimeClient.cs | 75 ++++++++++--------- UptimeSharp/UptimeSharp.csproj | 3 +- UptimeSharp/Utilities/UptimeSharpException.cs | 6 +- 11 files changed, 70 insertions(+), 67 deletions(-) create mode 100644 UptimeSharp/Models/Response/IResponse.cs rename UptimeSharp/Models/Response/{ResponseBase.cs => Response.cs} (90%) diff --git a/UptimeSharp.Tests/MonitorsTest.cs b/UptimeSharp.Tests/MonitorsTest.cs index 0a54c6d..d8c6a73 100644 --- a/UptimeSharp.Tests/MonitorsTest.cs +++ b/UptimeSharp.Tests/MonitorsTest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using UptimeSharp.Models; using Xunit; @@ -75,15 +76,7 @@ namespace UptimeSharp.Tests //)); List items = await client.GetMonitors(); - Monitor monitor = null; - - items.ForEach(item => - { - if (item.Name == "test_5") - { - monitor = item; - } - }); + Monitor monitor = items.SingleOrDefault(item => item.Name == "test_5"); Assert.True( monitor != null diff --git a/UptimeSharp/Components/Alert.cs b/UptimeSharp/Components/Alert.cs index 19fed43..197c5ee 100644 --- a/UptimeSharp/Components/Alert.cs +++ b/UptimeSharp/Components/Alert.cs @@ -65,7 +65,7 @@ namespace UptimeSharp { "alertContactValue", value } }); - return response.Status; + return response.Success; } @@ -102,7 +102,7 @@ namespace UptimeSharp { "alertContactID", alertID } }); - return response.Status; + return response.Success; } diff --git a/UptimeSharp/Components/Monitor.cs b/UptimeSharp/Components/Monitor.cs index 5499445..6030be3 100644 --- a/UptimeSharp/Components/Monitor.cs +++ b/UptimeSharp/Components/Monitor.cs @@ -41,7 +41,7 @@ namespace UptimeSharp RetrieveResponse response = await Request("getMonitors", cancellationToken, parameters.Convert()); - return response.Items; + return response.Items ?? new List(); } @@ -85,7 +85,7 @@ namespace UptimeSharp { "monitorID", monitorId.ToString() } }); - return response.Status; + return response.Success; } @@ -149,7 +149,7 @@ namespace UptimeSharp }; DefaultResponse response = await Request("newMonitor", cancellationToken, parameters.Convert()); - return response.Status; + return response.Success; } @@ -195,7 +195,7 @@ namespace UptimeSharp paramList.Add("monitorID", monitor.ID.ToString()); DefaultResponse response = await Request("editMonitor", cancellationToken, paramList); - return response.Status; + return response.Success; } } } \ No newline at end of file diff --git a/UptimeSharp/Models/Response/AlertResponse.cs b/UptimeSharp/Models/Response/AlertResponse.cs index 094b723..d690681 100644 --- a/UptimeSharp/Models/Response/AlertResponse.cs +++ b/UptimeSharp/Models/Response/AlertResponse.cs @@ -7,7 +7,7 @@ namespace UptimeSharp.Models /// Alert Response /// [JsonObject] - internal class AlertResponse : ResponseBase + internal class AlertResponse : Response { /// /// Gets or sets the item dictionary. diff --git a/UptimeSharp/Models/Response/DefaultResponse.cs b/UptimeSharp/Models/Response/DefaultResponse.cs index 208422c..85eba0b 100644 --- a/UptimeSharp/Models/Response/DefaultResponse.cs +++ b/UptimeSharp/Models/Response/DefaultResponse.cs @@ -6,5 +6,5 @@ namespace UptimeSharp.Models /// Default Response /// [JsonObject] - internal class DefaultResponse : ResponseBase {} + internal class DefaultResponse : Response { } } diff --git a/UptimeSharp/Models/Response/IResponse.cs b/UptimeSharp/Models/Response/IResponse.cs new file mode 100644 index 0000000..a5e3dda --- /dev/null +++ b/UptimeSharp/Models/Response/IResponse.cs @@ -0,0 +1,10 @@ +namespace UptimeSharp.Models +{ + internal interface IResponse + { + string ErrorCode { get; set; } + string ErrorMessage { get; set; } + string RawStatus { get; set; } + bool Success { get; } + } +} diff --git a/UptimeSharp/Models/Response/ResponseBase.cs b/UptimeSharp/Models/Response/Response.cs similarity index 90% rename from UptimeSharp/Models/Response/ResponseBase.cs rename to UptimeSharp/Models/Response/Response.cs index 0473c9a..58f9dc4 100644 --- a/UptimeSharp/Models/Response/ResponseBase.cs +++ b/UptimeSharp/Models/Response/Response.cs @@ -6,7 +6,7 @@ namespace UptimeSharp.Models /// Base for Responses /// [JsonObject] - internal class ResponseBase + internal class Response : IResponse { /// @@ -28,7 +28,7 @@ namespace UptimeSharp.Models public string ErrorMessage { get; set; } /// - /// Gets or sets a value indicating whether this is status. + /// Gets or sets a value indicating whether this is status. /// /// /// "ok" or "fail" @@ -37,13 +37,13 @@ namespace UptimeSharp.Models public string RawStatus { get; set; } /// - /// Gets or sets a value indicating whether this is status. + /// Gets or sets a value indicating whether this is success. /// /// /// true if status is OK; otherwise, false. /// [JsonIgnore] - public bool Status + public bool Success { get { return RawStatus == "ok"; } } diff --git a/UptimeSharp/Models/Response/RetrieveResponse.cs b/UptimeSharp/Models/Response/RetrieveResponse.cs index 25573dc..c122026 100644 --- a/UptimeSharp/Models/Response/RetrieveResponse.cs +++ b/UptimeSharp/Models/Response/RetrieveResponse.cs @@ -1,5 +1,5 @@ -using System.Collections.Generic; -using Newtonsoft.Json; +using Newtonsoft.Json; +using System.Collections.Generic; namespace UptimeSharp.Models { @@ -7,7 +7,7 @@ namespace UptimeSharp.Models /// Monitor Response /// [JsonObject] - internal class RetrieveResponse : ResponseBase + internal class RetrieveResponse : Response { /// /// Gets or sets the item dictionary. @@ -30,7 +30,7 @@ namespace UptimeSharp.Models { get { - return ItemDictionary != null ? ItemDictionary["monitor"] : null; + return ItemDictionary != null ? ItemDictionary["monitor"] : null; } } } diff --git a/UptimeSharp/UptimeClient.cs b/UptimeSharp/UptimeClient.cs index 40d6515..c95fc7b 100644 --- a/UptimeSharp/UptimeClient.cs +++ b/UptimeSharp/UptimeClient.cs @@ -8,6 +8,7 @@ using System.Net.Http; using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; +using UptimeSharp.Models; namespace UptimeSharp { @@ -54,6 +55,12 @@ namespace UptimeSharp public Action PreRequest { get; set; } + /// + /// The fail codes that don't raise exceptions + /// + private static readonly string[] successFailCodes = new string[] { "212", "221" }; + + /// /// Initializes a new instance of the class. /// @@ -133,8 +140,11 @@ namespace UptimeSharp throw new UptimeSharpException(exc.Message, exc); } - // validate HTTP response - ValidateResponse(response); + // HTTP error + if (!response.IsSuccessStatusCode) + { + throw new UptimeSharpException("Request Exception: {0} (Code: {1})", response.ReasonPhrase, response.StatusCode.ToString()); + } // cache headers lastHeaders = response.Headers; @@ -145,8 +155,6 @@ namespace UptimeSharp // cache response lastResponseData = responseString; - responseString = responseString.Replace("[]", "{}"); - // deserialize object T parsedResponse = JsonConvert.DeserializeObject( responseString, @@ -154,7 +162,7 @@ namespace UptimeSharp { Error = (object sender, ErrorEventArgs args) => { - throw new UptimeSharpException(String.Format("Parse error: {0}", args.ErrorContext.Error.Message)); + throw new UptimeSharpException(String.Format("Parse Exception: {0}", args.ErrorContext.Error.Message)); }, Converters = { @@ -165,6 +173,9 @@ namespace UptimeSharp } ); + // validate response + ValidateResponse(parsedResponse as IResponse); + return parsedResponse; } @@ -177,46 +188,38 @@ namespace UptimeSharp /// /// Error retrieving response /// - protected void ValidateResponse(HttpResponseMessage response) + internal void ValidateResponse(IResponse response) { - // no error found - if (response.StatusCode == HttpStatusCode.OK) + // it's a success ;-) + if (response.Success) { return; } - //string exceptionString = response.ReasonPhrase; - //bool isPocketError = response.Headers.Contains("X-Error"); + // don't raise exceptions for minor error codes + if (successFailCodes.Contains(response.ErrorCode)) + { + return; + } - //// fetch custom pocket headers - //string error = TryGetHeaderValue(response.Headers, "X-Error"); - //int errorCode = Convert.ToInt32(TryGetHeaderValue(response.Headers, "X-Error-Code")); + // create exception + UptimeSharpException exception = new UptimeSharpException( + "UptimeRobot Exception: {0} (Code: {1})\n{2}", + null, + response.ErrorMessage, + response.ErrorCode, + "http://uptimerobot.com/api.asp#errorMessages" + ); - //// create exception strings - //if (isPocketError) - //{ - // exceptionString = String.Format("Pocket error: {0} ({1}) ", error, errorCode); - //} - //else - //{ - // exceptionString = String.Format("Request error: {0} ({1})", response.ReasonPhrase, (int)response.StatusCode); - //} + // add custom fields + exception.Error = response.ErrorMessage; + exception.ErrorCode = response.ErrorCode; - //// create exception - //PocketException exception = new PocketException(exceptionString); + // add to generic exception data + exception.Data.Add("Error", response.ErrorMessage); + exception.Data.Add("ErrorCode", response.ErrorCode); - //if (isPocketError) - //{ - // // add custom pocket fields - // exception.PocketError = error; - // exception.PocketErrorCode = errorCode; - - // // add to generic exception data - // exception.Data.Add("X-Error", error); - // exception.Data.Add("X-Error-Code", errorCode); - //} - - //throw exception; + throw exception; } } } diff --git a/UptimeSharp/UptimeSharp.csproj b/UptimeSharp/UptimeSharp.csproj index c83bd78..7ff28fb 100644 --- a/UptimeSharp/UptimeSharp.csproj +++ b/UptimeSharp/UptimeSharp.csproj @@ -50,7 +50,8 @@ - + + diff --git a/UptimeSharp/Utilities/UptimeSharpException.cs b/UptimeSharp/Utilities/UptimeSharpException.cs index d41e38e..00dd33d 100644 --- a/UptimeSharp/Utilities/UptimeSharpException.cs +++ b/UptimeSharp/Utilities/UptimeSharpException.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; namespace UptimeSharp { @@ -17,7 +13,7 @@ namespace UptimeSharp /// /// The pocket error code. /// - public int? ErrorCode { get; set; } + public string ErrorCode { get; set; } /// /// Gets or sets the UptimeRobot error.