/// <summary> /// Constructs MarketplaceWebServiceException with information available from service /// </summary> /// <param name="message">Overview of error</param> /// <param name="statusCode">HTTP status code for error response</param> /// <param name="errorCode">Error Code returned by the service</param> /// <param name="errorType">Error type. Possible types: Sender, Receiver or Unknown</param> /// <param name="requestId">Request ID returned by the service</param> /// <param name="xml">Compete xml found in response</param> /// <param name="rhm">Response Header Metadata</param> public MarketplaceWebServiceException(String message, HttpStatusCode statusCode, String errorCode, String errorType, String requestId, String xml, ResponseHeaderMetadata2 rhm) : this(message, statusCode, rhm) { this.errorCode = errorCode; this.errorType = errorType; this.requestId = requestId; this.xml = xml; this.responseHeaderMetadata = rhm; }
/// <summary> /// Constructs MarketplaceWebServiceException with message and wrapped exception /// </summary> /// <param name="message">Overview of error</param> /// <param name="t">Wrapped exception</param> public MarketplaceWebServiceException(String message, Exception t) : base(message, t) { this.message = message; if (t is MarketplaceWebServiceException) { MarketplaceWebServiceException ex = (MarketplaceWebServiceException)t; this.statusCode = ex.StatusCode; this.errorCode = ex.ErrorCode; this.errorType = ex.ErrorType; this.requestId = ex.RequestId; this.xml = ex.XML; this.responseHeaderMetadata = ex.ResponseHeaderMetadata; } }
/** * Look for additional error strings in the response and return formatted exception */ private MarketplaceWebServiceException ReportAnyErrors(String responseBody, HttpStatusCode status, Exception e, ResponseHeaderMetadata2 rhm) { MarketplaceWebServiceException 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 MarketplaceWebServiceException(message, status, code, "Unknown", requestId, responseBody, rhm); } else if (errorMatcherTwo.Success) { String code = errorMatcherTwo.Groups[1].Value; String message = errorMatcherTwo.Groups[2].Value; String requestId = errorMatcherTwo.Groups[4].Value; ex = new MarketplaceWebServiceException(message, status, code, "Unknown", requestId, responseBody, rhm); } else { ex = new MarketplaceWebServiceException("Internal Error", status, rhm); } } else { ex = new MarketplaceWebServiceException("Internal Error", status, rhm); } return(ex); }
/// <summary> /// Constructs MarketplaceWebServiceException with message and status code /// </summary> /// <param name="message">Overview of error</param> /// <param name="statusCode">HTTP status code for error response</param> /// <param name="rhm">Response Header Metadata</param> public MarketplaceWebServiceException(String message, HttpStatusCode statusCode, ResponseHeaderMetadata2 rhm) : this(message) { this.statusCode = statusCode; this.responseHeaderMetadata = rhm; }
/** * Invoke request and return response */ private T Invoke <T, K>(IDictionary <String, String> parameters, K clazz) { String actionName = parameters["Action"]; T response = default(T); String responseBody = null; HttpStatusCode statusCode = default(HttpStatusCode); ResponseHeaderMetadata2 rhm = null; // Verify service URL is set. if (String.IsNullOrEmpty(config.ServiceURL)) { throw new MarketplaceWebServiceException(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); HttpWebRequest request; bool isStreamingResponse = ExpectStreamingResponse(typeof(K)); bool shouldRetry = true; int retries = 0; do { /* Submit the request and read response body */ try { RequestType requestType = GetMarketplaceWebServiceRequestType(typeof(K)); switch (requestType) { case RequestType.STREAMING: { SubmitFeedRequest req = clazz as SubmitFeedRequest; if (req != null) { // SubmitFeedRequests can configure the content type. request = ConfigureWebRequest(queryString, req.ContentType); } else { // Send request using a default content-type. request = ConfigureWebRequest(queryString, new ContentType("application/octet-stream")); } } break; default: request = ConfigureWebRequest(requestData.Length); break; } WebHeaderCollection headers = request.Headers; using (Stream requestStream = request.GetRequestStream()) { switch (requestType) { case RequestType.STREAMING: Stream inputStream = GetTransferStream(clazz, StreamType.REQUEST_STREAM); inputStream.Position = 0; CopyStream(inputStream, requestStream); break; default: requestStream.Write(requestData, 0, requestData.Length); break; } requestStream.Close(); } using (HttpWebResponse httpResponse = request.GetResponse() as HttpWebResponse) { statusCode = httpResponse.StatusCode; rhm = new ResponseHeaderMetadata2( httpResponse.GetResponseHeader("x-mws-request-id"), httpResponse.GetResponseHeader("x-mws-response-context"), httpResponse.GetResponseHeader("x-mws-timestamp")); if (isStreamingResponse && statusCode == HttpStatusCode.OK) { response = HandleStreamingResponse <T>(httpResponse, clazz); } else { StreamReader reader = new StreamReader(httpResponse.GetResponseStream(), Encoding.UTF8); responseBody = reader.ReadToEnd(); XmlSerializer serlizer = new XmlSerializer(typeof(T)); response = (T)serlizer.Deserialize(new StringReader(responseBody)); } PropertyInfo pi = typeof(T).GetProperty("ResponseHeaderMetadata2"); pi.SetValue(response, rhm, null); shouldRetry = false; } /* Attempt to deserialize response into <Action> Response type */ } /* 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 MarketplaceWebServiceException(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 MarketplaceWebServiceException( error.Message, statusCode, error.Code, error.Type, errorResponse.RequestId, errorResponse.ToXML(), rhm); } /* Rethrow on deserializer error */ catch (Exception e) { if (e is MarketplaceWebServiceException) { throw e; } else { MarketplaceWebServiceException se = ReportAnyErrors(responseBody, statusCode, e, rhm); throw se; } } } /* Catch other exceptions, attempt to convert to formatted exception, * else rethrow wrapped exception */ catch (Exception e) { throw new MarketplaceWebServiceException(e); } } while (shouldRetry); return(response); }