diff --git a/UptimeSharp.Tests/AlertsTest.cs b/UptimeSharp.Tests/AlertsTest.cs index 789bdd2..570d3bb 100644 --- a/UptimeSharp.Tests/AlertsTest.cs +++ b/UptimeSharp.Tests/AlertsTest.cs @@ -32,7 +32,7 @@ namespace UptimeSharp.Tests [Fact] public void AddInvalidAlertWithTypeSms() { - Assert.Throws(() => + Assert.Throws(() => { client.AddAlert(Models.AlertType.SMS, "+436601289172"); }); @@ -42,7 +42,7 @@ namespace UptimeSharp.Tests [Fact] public void AddInvalidAlertWithTypeTwitter() { - Assert.Throws(() => + Assert.Throws(() => { client.AddAlert(Models.AlertType.Twitter, "artistandsocial"); }); diff --git a/UptimeSharp.sln b/UptimeSharp.sln index e0e41a6..05d29c6 100644 --- a/UptimeSharp.sln +++ b/UptimeSharp.sln @@ -5,6 +5,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UptimeSharp", "UptimeSharp\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UptimeSharp.Tests", "UptimeSharp.Tests\UptimeSharp.Tests.csproj", "{7AB536B7-1A99-44A7-B5AA-E36E9C7F09F4}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApplication1", "ConsoleApplication1\ConsoleApplication1.csproj", "{2A5CC10E-451C-4978-A9B7-9F2889A18BCF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -19,6 +21,10 @@ Global {7AB536B7-1A99-44A7-B5AA-E36E9C7F09F4}.Debug|Any CPU.Build.0 = Debug|Any CPU {7AB536B7-1A99-44A7-B5AA-E36E9C7F09F4}.Release|Any CPU.ActiveCfg = Release|Any CPU {7AB536B7-1A99-44A7-B5AA-E36E9C7F09F4}.Release|Any CPU.Build.0 = Release|Any CPU + {2A5CC10E-451C-4978-A9B7-9F2889A18BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2A5CC10E-451C-4978-A9B7-9F2889A18BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A5CC10E-451C-4978-A9B7-9F2889A18BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2A5CC10E-451C-4978-A9B7-9F2889A18BCF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/UptimeSharp/APIException.cs b/UptimeSharp/APIException.cs deleted file mode 100644 index becdccd..0000000 --- a/UptimeSharp/APIException.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace UptimeSharp -{ - /// - /// custom UptimeRobot API Exceptions - /// - public class APIException : Exception - { - /// - /// Gets or sets the UptimeRobot error code. - /// - /// - /// The pocket error code. - /// - public int? UptimeErrorCode { get; set; } - - /// - /// Gets or sets the UptimeRobot error. - /// - /// - /// The pocket error. - /// - public string UptimeError { get; set; } - - - /// - /// Initializes a new instance of the class. - /// - public APIException() - : base() { } - - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - public APIException(string message) - : base(message) { } - - - /// - /// Initializes a new instance of the class. - /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - public APIException(string message, Exception innerException) - : base(message, innerException) { } - - - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - protected APIException(SerializationInfo info, StreamingContext context) - : base(info, context) { } - } -} diff --git a/UptimeSharp/Components/Alert.cs b/UptimeSharp/Components/Alert.cs index 958996d..1b8b57c 100644 --- a/UptimeSharp/Components/Alert.cs +++ b/UptimeSharp/Components/Alert.cs @@ -47,7 +47,7 @@ namespace UptimeSharp { if (type == AlertType.SMS || type == AlertType.Twitter) { - throw new APIException("AlertType.SMS and AlertType.Twitter are not supported by the UptimeRobot API"); + throw new UptimeSharpException("AlertType.SMS and AlertType.Twitter are not supported by the UptimeRobot API"); } return Get("newAlertContact", diff --git a/UptimeSharp/Models/Response/ResponseBase.cs b/UptimeSharp/Models/Response/ResponseBase.cs index da02117..3c99b0c 100644 --- a/UptimeSharp/Models/Response/ResponseBase.cs +++ b/UptimeSharp/Models/Response/ResponseBase.cs @@ -8,6 +8,25 @@ namespace UptimeSharp.Models [DataContract] internal class ResponseBase { + + /// + /// Gets or sets the error code. + /// + /// + /// The error code. + /// + [DataMember(Name = "id")] + public string ErrorCode { get; set; } + + /// + /// Gets or sets the error message. + /// + /// + /// The error message. + /// + [DataMember(Name = "message")] + public string ErrorMessage { get; set; } + /// /// Gets or sets a value indicating whether this is status. /// diff --git a/UptimeSharp/UptimeClient.cs b/UptimeSharp/UptimeClient.cs index 8d236e5..75788ea 100644 --- a/UptimeSharp/UptimeClient.cs +++ b/UptimeSharp/UptimeClient.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Reflection; namespace UptimeSharp { @@ -76,7 +77,7 @@ namespace UptimeSharp IRestResponse response = _restClient.Execute(request); LastRequestData = response; - ValidateResponse(response); + ValidateResponse(response); return response.Data; } @@ -134,7 +135,7 @@ namespace UptimeSharp /// The name. /// The value. /// - public static Parameter Parameter(string name, object value) + internal static Parameter Parameter(string name, object value) { return new Parameter() { @@ -150,45 +151,60 @@ namespace UptimeSharp /// /// The response. /// - /// + /// /// Error retrieving response /// - protected void ValidateResponse(IRestResponse response) + protected void ValidateResponse(IRestResponse response) where T : new() { - if (response.StatusCode != HttpStatusCode.OK) + Type responseType = response.Data.GetType(); + + // get status property from ResponseBase POCO + PropertyInfo statusProp = responseType.GetProperty("Status"); + object status = statusProp.GetValue(response.Data, null); + + // Error from UptimeSharp + if (status.Equals(false)) { - //Parameter error = response.Headers[1]; - //Parameter errorCode = response.Headers[2]; + // get error properties from response + PropertyInfo errorProp = responseType.GetProperty("ErrorMessage"); + object error = errorProp.GetValue(response.Data, null); - //string exceptionString = response.Content; - - //bool isPocketError = error.Name == "X-Error"; - - //// update message to include pocket response data - //if (isPocketError) - //{ - // exceptionString = exceptionString + "\nPocketResponse: (" + errorCode.Value + ") " + error.Value; - //} + PropertyInfo errorCodeProp = responseType.GetProperty("ErrorCode"); + object errorCode = errorCodeProp.GetValue(response.Data, null); // create exception - APIException exception = new APIException("Request Exception", response.ErrorException); + UptimeSharpException exception = new UptimeSharpException( + "UptimeRobot Exception: {0} (Code: {1})\n{2}", + response.ErrorException, + error, + errorCode, + "http://uptimerobot.com/api.asp#errorMessages" + ); - //if (isPocketError) - //{ - // // add custom pocket fields - // exception.PocketError = error.Value.ToString(); - // exception.PocketErrorCode = Convert.ToInt32(errorCode.Value); + // add custom pocket fields + exception.Error = error.ToString(); + exception.ErrorCode = Convert.ToInt32(errorCode); - // // add to generic exception data - // exception.Data.Add(error.Name, error.Value); - // exception.Data.Add(errorCode.Name, errorCode.Value); - //} + // add to generic exception data + exception.Data.Add("Error", error); + exception.Data.Add("ErrorCode", errorCode); throw exception; } + // HTTP Request Error + else if (response.StatusCode != HttpStatusCode.OK) + { + throw new UptimeSharpException( + "Request Exception: {0} (Code: {1})", + response.ErrorException, + response.ErrorMessage, + response.StatusCode + ); + } + // Exception by RestSharp else if (response.ErrorException != null) { - throw new APIException("Error retrieving response", response.ErrorException); + throw new UptimeSharpException("Error retrieving response", response.ErrorException); } } } diff --git a/UptimeSharp/UptimeSharp.csproj b/UptimeSharp/UptimeSharp.csproj index d07498e..c3562c9 100644 --- a/UptimeSharp/UptimeSharp.csproj +++ b/UptimeSharp/UptimeSharp.csproj @@ -51,7 +51,7 @@ - + diff --git a/UptimeSharp/UptimeSharpException.cs b/UptimeSharp/UptimeSharpException.cs new file mode 100644 index 0000000..dfe9a98 --- /dev/null +++ b/UptimeSharp/UptimeSharpException.cs @@ -0,0 +1,79 @@ +using System; +using System.Runtime.Serialization; + +namespace UptimeSharp +{ + /// + /// custom UptimeRobot API Exceptions + /// + public class UptimeSharpException : Exception + { + /// + /// Gets or sets the UptimeRobot error code. + /// + /// + /// The pocket error code. + /// + public int? ErrorCode { get; set; } + + /// + /// Gets or sets the UptimeRobot error. + /// + /// + /// The pocket error. + /// + public string Error { get; set; } + + + /// + /// Initializes a new instance of the class. + /// + public UptimeSharpException() + : base() { } + + + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public UptimeSharpException(string message) + : base(message) { } + + + /// + /// Initializes a new instance of the class. + /// + /// The message. + /// The arguments. + public UptimeSharpException(string message, params object[] args) + : base(string.Format(message, args)) { } + + + /// + /// Initializes a new instance of the class. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public UptimeSharpException(string message, Exception innerException) + : base(message, innerException) { } + + + /// + /// Initializes a new instance of the class. + /// + /// The message. + /// The inner exception. + /// The arguments. + public UptimeSharpException(string message, Exception innerException, params object[] args) + : base(string.Format(message, args), innerException) { } + + + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + protected UptimeSharpException(SerializationInfo info, StreamingContext context) + : base(info, context) { } + } +}