/ChargifyDotNET/Source/Chargify.NET/ChargifyException.cs
C# | 276 lines | 158 code | 20 blank | 98 comment | 11 complexity | f4e58665b2ac2ee0909ce760906dabab MD5 | raw file
-
- #region License, Terms and Conditions
- //
- // ChargifyException.cs
- //
- // Authors: Kori Francis <twitter.com/djbyter>, David Ball
- // Copyright (C) 2010 Clinical Support Systems, Inc. All rights reserved.
- //
- // THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW:
- //
- // Permission is hereby granted, free of charge, to any person obtaining a
- // copy of this software and associated documentation files (the "Software"),
- // to deal in the Software without restriction, including without limitation
- // the rights to use, copy, modify, merge, publish, distribute, sublicense,
- // and/or sell copies of the Software, and to permit persons to whom the
- // Software is furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- // DEALINGS IN THE SOFTWARE.
- //
- #endregion
-
- namespace ChargifyNET
- {
- #region Imports
- using System;
- using System.Net;
- using System.Diagnostics;
- using System.Runtime.Serialization;
- using System.Security.Permissions;
- using System.Xml;
- using System.Collections.Generic;
- using System.IO;
- using ChargifyNET.Json;
- using System.Xml.Linq;
- using System.Linq;
- #endregion
-
- /// <summary>
- /// Error returned from Chargify after an unsuccessful operation
- /// </summary>
- [Serializable]
- public class ChargifyError
- {
- /// <summary>
- /// The message from Chargify
- /// </summary>
- public string Message { get; private set; }
-
- #region Constructors
- /// <summary>
- /// Constructor
- /// </summary>
- internal ChargifyError() { }
-
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="message">The string error message to relay to the user</param>
- internal ChargifyError(string message)
- {
- this.Message = message;
- }
-
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="errorNode">The XML node that contains the error message</param>
- internal ChargifyError(XmlNode errorNode)
- {
- this.Message = errorNode.Value;
- }
-
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="errorStr">The JsonString obj that contains the error message</param>
- internal ChargifyError(JsonString errorStr)
- {
- this.Message = errorStr.Value;
- }
-
- #endregion
-
- /// <summary>
- /// Method to parse the errors returned from Chargify after an unsuccessful interaction
- /// </summary>
- /// <param name="response">The HttpWebResponse instance which contains the error response</param>
- /// <returns>The list of errors returned from Chargify</returns>
- internal static List<ChargifyError> ParseChargifyErrors(HttpWebResponse response)
- {
- if (response != null)
- {
- using (StreamReader reader = new StreamReader(response.GetResponseStream()))
- {
- string errorResponse = reader.ReadToEnd();
- List<ChargifyError> errors = new List<ChargifyError>();
-
- // Response is frequently " " ...
- if (string.IsNullOrEmpty(errorResponse.Trim())) return errors;
-
- if (errorResponse.IsXml())
- {
- // New way - Linq-y
- XDocument xdoc = XDocument.Parse(errorResponse);
- var results = from e in xdoc.Descendants("errors")
- select new ChargifyError
- {
- Message = e.Value
- };
- errors = results.ToList();
- }
- else if (errorResponse.IsJSON())
- {
- // slightly different json response from the usual
- int position = 0;
- JsonObject obj = JsonObject.Parse(errorResponse, ref position);
- if (obj.ContainsKey("errors"))
- {
- JsonArray array = obj["errors"] as JsonArray;
- for (int i = 0; i <= array.Length - 1; i++)
- {
- if (((array.Items[i] as JsonString) != null)&&(!string.IsNullOrEmpty((array.Items[i] as JsonString).Value)))
- {
- JsonString errorStr = array.Items[i] as JsonString;
- ChargifyError anError = new ChargifyError(errorStr);
- if (!errors.Contains(anError))
- {
- errors.Add(anError);
- }
- }
- }
- }
- }
- return errors;
- }
- }
- else
- {
- throw new ChargifyNetException("Unknown Error");
- }
- }
- }
-
- /// <summary>
- /// Exception thrown by Chargify.NET library when things don't add up
- /// </summary>
- [Serializable]
- public class ChargifyNetException : Exception
- {
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="message">The message of this exception</param>
- public ChargifyNetException(string message) : base(message)
- {
- }
- }
-
- /// <summary>
- /// Exception thrown by the chargify system when a request fails
- /// </summary>
- [DebuggerDisplay("Status Description: {StatusDescription}, Status Code: {StatusCode}, Error Messages: {ErrorMessages.Count}")]
- [Serializable]
- public class ChargifyException : Exception
- {
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="errorResponse">The response that caused the exception</param>
- /// <param name="wex">The original web exception. This becomes the inner exception of ths exception</param>
- public ChargifyException(HttpWebResponse errorResponse, WebException wex) :
- base(string.Format("The server returned '{0}' with the status code {1} ({1:d}).", errorResponse.StatusDescription, errorResponse.StatusCode), wex)
- {
- _statusDescription = errorResponse.StatusDescription;
- _statusCode = errorResponse.StatusCode;
- // if there are any errors, parse them for user consumption
- _errors = ChargifyError.ParseChargifyErrors(errorResponse);
- }
-
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="errorResponse">The response that caused the exception</param>
- /// <param name="wex">The original web exception. This becomes the inner exception of ths exception</param>
- /// <param name="postData">The data posted that could have potentially caused the exception.</param>
- public ChargifyException(HttpWebResponse errorResponse, WebException wex, string postData) :
- base(string.Format("The server returned '{0}' with the status code {1} ({1:d}) when posting '{2}'.", errorResponse.StatusDescription, errorResponse.StatusCode, postData), wex)
- {
- _statusDescription = errorResponse.StatusDescription;
- _statusCode = errorResponse.StatusCode;
- _postData = postData;
- // if there are any errors, parse them for user consumption
- _errors = ChargifyError.ParseChargifyErrors(errorResponse);
- }
-
- /// <summary>
- /// Get the status description
- /// </summary>
- public string StatusDescription
- {
- get
- {
- return _statusDescription;
- }
- }
- private string _statusDescription = "";
-
- /// <summary>
- /// Get the status code
- /// </summary>
- public HttpStatusCode StatusCode
- {
- get
- {
- return _statusCode;
- }
- }
- private HttpStatusCode _statusCode = HttpStatusCode.Accepted;
-
- /// <summary>
- /// Get the last data posted that potentially caused the exception
- /// </summary>
- public string LastDataPosted
- {
- get
- {
- return _postData;
- }
- }
- private string _postData = string.Empty;
-
- /// <summary>
- /// List of ChargifyErrors returned from Chargify.
- /// </summary>
- public List<ChargifyError> ErrorMessages
- {
- get
- {
- return _errors;
- }
- }
- private List<ChargifyError> _errors = null;
-
- /// <summary>
- /// Get object data
- /// </summary>
- [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
- public override void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- base.GetObjectData(info, context);
- }
-
- /// <summary>
- /// Pretty output for this exception
- /// </summary>
- /// <returns>Request, response and errors</returns>
- public override string ToString()
- {
- // Used for the LogResponse Action
- string retVal = string.Empty;
- retVal += string.Format("Request: {0}\n", LastDataPosted);
- retVal += string.Format("Response: {0} {1}\n", StatusCode.ToString(), StatusDescription.ToString());
- retVal += string.Format("Errors: {0}\n", string.Join(", ", _errors.ToList().Select(e => e.Message).ToArray()));
- return retVal;
- }
- }
- }