/// <summary> /// Constructs FBAInventoryServiceMWSException with message and wrapped exception /// </summary> /// <param name="message">Overview of error</param> /// <param name="t">Wrapped exception</param> public FBAInventoryServiceMWSException(String message, Exception t) : base(message, t) { this.message = message; if (t is FBAInventoryServiceMWSException) { FBAInventoryServiceMWSException ex = (FBAInventoryServiceMWSException)t; this.statusCode = ex.StatusCode; this.errorCode = ex.ErrorCode; this.errorType = ex.ErrorType; this.requestId = ex.RequestId; this.xml = ex.XML; } }
/** * Look for additional error strings in the response and return formatted exception */ private FBAInventoryServiceMWSException ReportAnyErrors(String responseBody, HttpStatusCode status, Exception e) { FBAInventoryServiceMWSException ex = null; if (responseBody != null && responseBody.StartsWith("<")) { Match errorMatcherOne = Regex.Match(responseBody, "<RequestId>(.*)</RequestId>.*<Error>" + "<Code>(.*)</Code><Message>(.*)</Message></Error>.*(<Error>)?", RegexOptions.Multiline); Match errorMatcherTwo = Regex.Match(responseBody, "<Error><Code>(.*)</Code><Message>(.*)" + "</Message></Error>.*(<Error>)?.*<RequestID>(.*)</RequestID>", RegexOptions.Multiline); if (errorMatcherOne.Success) { String requestId = errorMatcherOne.Groups[1].Value; String code = errorMatcherOne.Groups[2].Value; String message = errorMatcherOne.Groups[3].Value; ex = new FBAInventoryServiceMWSException(message, status, code, "Unknown", requestId, responseBody); } else if (errorMatcherTwo.Success) { String code = errorMatcherTwo.Groups[1].Value; String message = errorMatcherTwo.Groups[2].Value; String requestId = errorMatcherTwo.Groups[4].Value; ex = new FBAInventoryServiceMWSException(message, status, code, "Unknown", requestId, responseBody); } else { ex = new FBAInventoryServiceMWSException("Internal Error", status); } } else { ex = new FBAInventoryServiceMWSException("Internal Error", status); } return(ex); }
/** * Invoke request and return response */ private T Invoke <T>(IDictionary <String, String> parameters) { String actionName = parameters["Action"]; T response = default(T); String responseBody = null; HttpStatusCode statusCode = default(HttpStatusCode); // Verify service URL is set. if (String.IsNullOrEmpty(config.ServiceURL)) { throw new FBAInventoryServiceMWSException(new ArgumentException( "Missing serviceUrl configuration value. You may obtain a list of valid MWS URLs by consulting the MWS Developer's Guide, or reviewing the sample code published along side this library.")); } /* Add required request parameters */ AddRequiredParameters(parameters); String queryString = GetParametersAsString(parameters); byte[] requestData = new UTF8Encoding().GetBytes(queryString); bool shouldRetry = true; int retries = 0; do { HttpWebRequest request = ConfigureWebRequest(requestData.Length); /* Submit the request and read response body */ try { using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(requestData, 0, requestData.Length); } using (HttpWebResponse httpResponse = request.GetResponse() as HttpWebResponse) { statusCode = httpResponse.StatusCode; StreamReader reader = new StreamReader(httpResponse.GetResponseStream(), Encoding.UTF8); responseBody = reader.ReadToEnd(); } /* Attempt to deserialize response into <Action> Response type */ XmlSerializer serlizer = new XmlSerializer(typeof(T)); response = (T)serlizer.Deserialize(new StringReader(responseBody)); shouldRetry = false; } /* Web exception is thrown on unsucessful responses */ catch (WebException we) { shouldRetry = false; using (HttpWebResponse httpErrorResponse = (HttpWebResponse)we.Response as HttpWebResponse) { if (httpErrorResponse == null) { throw new FBAInventoryServiceMWSException(we); } statusCode = httpErrorResponse.StatusCode; StreamReader reader = new StreamReader(httpErrorResponse.GetResponseStream(), Encoding.UTF8); responseBody = reader.ReadToEnd(); } /* Attempt to deserialize response into ErrorResponse type */ try { XmlSerializer serlizer = new XmlSerializer(typeof(ErrorResponse)); ErrorResponse errorResponse = (ErrorResponse)serlizer.Deserialize(new StringReader(responseBody)); Error error = errorResponse.Error[0]; bool retriableError = (statusCode == HttpStatusCode.InternalServerError || statusCode == HttpStatusCode.ServiceUnavailable); retriableError = retriableError && error.Code != "RequestThrottled"; if (retriableError && retries < config.MaxErrorRetry) { PauseOnRetry(++retries); shouldRetry = true; continue; } else { shouldRetry = false; } /* Throw formatted exception with information available from the error response */ throw new FBAInventoryServiceMWSException( error.Message, statusCode, error.Code, error.Type, errorResponse.RequestId, errorResponse.ToXML()); } /* Rethrow on deserializer error */ catch (Exception e) { if (e is FBAInventoryServiceMWSException) { throw e; } else { FBAInventoryServiceMWSException se = ReportAnyErrors(responseBody, statusCode, e); throw se; } } } /* Catch other exceptions, attempt to convert to formatted exception, * else rethrow wrapped exception */ catch (Exception e) { throw new FBAInventoryServiceMWSException(e); } } while (shouldRetry); return(response); }