public BizwebSharpException(HttpStatusCode httpStatusCode, Dictionary <string, IEnumerable <string> > errors, string message, string rawBody, RequestSimpleInfo requestInfo = null) : base(message) { HttpStatusCode = httpStatusCode; Errors = errors; RawBody = rawBody; RequestInfo = requestInfo; }
private static async Task <RequestSimpleInfo> CreateRequestSimpleInfoAsync(HttpRequestMessage reqMsg) { string rawRequest = null; if (reqMsg.Content != null) { rawRequest = await reqMsg.Content.ReadAsStringAsync(); } var requestInfo = new RequestSimpleInfo { Url = reqMsg.RequestUri.AbsoluteUri, Method = reqMsg.Method.ToString(), Body = rawRequest }; if (reqMsg.Headers != null && reqMsg.Headers.Any()) { requestInfo.Header = string.Join("\n", reqMsg.Headers.Select(h => $"{h.Key}: { string.Join(", ", h.Value)}")); } return(requestInfo); }
/// <summary> /// Checks a response for exceptions or invalid status codes. Throws an exception when necessary. /// </summary> /// <param name="response">The response.</param> /// <param name="requestInfo">An simple request info.</param> /// <returns></returns> public static async Task CheckResponseExceptionsAsync(HttpResponseMessage response, RequestSimpleInfo requestInfo = null) { var statusCode = (int)response.StatusCode; // No error if response was between 200 and 300. if (statusCode >= 200 && statusCode < 300) { return; } var rawResponse = response.Content != null ? await response.Content.ReadAsStringAsync() : null; var contentType = response.Content?.Headers.GetValues("Content-Type").FirstOrDefault() ?? string.Empty; var message = $"Response did not indicate success. Status: {statusCode} {response.ReasonPhrase}.";; Dictionary <string, IEnumerable <string> > errors; if (contentType.StartsWithIgnoreCase("application/json") || contentType.StartsWithIgnoreCase("text/json")) { errors = ParseErrorJson(rawResponse); if (errors == null) { errors = new Dictionary <string, IEnumerable <string> > { { $"{statusCode} {response.ReasonPhrase}", new[] { message } } }; } else { var firstError = errors.First(); message = $"{firstError.Key}: {string.Join(", ", firstError.Value)}"; } } else { errors = new Dictionary <string, IEnumerable <string> > { { $"{statusCode} {response.ReasonPhrase}", new[] { message } }, { "NoJsonError", new[] { "Response did not return JSON, unable to parse error message (if any)." } } }; } // If the error was caused by reaching the API rate limit, throw a rate limit exception. if (statusCode == 429 /* Too many requests */) { var listMessage = "Exceeded 2 calls per second for api client. Reduce request rates to resume uninterrupted service."; var rateLimitMessage = $"Error: {listMessage}"; // Shopify used to return JSON for rate limit exceptions, but then made an unannounced change and started returing HTML. // This dictionary is an attempt at preserving what was previously returned. errors.Add("Error", new List <string> { listMessage }); throw new ApiRateLimitException(response.StatusCode, errors, rateLimitMessage, rawResponse, requestInfo); } throw new BizwebSharpException(response.StatusCode, errors, message, rawResponse, requestInfo); //if (response.ErrorException != null) //{ // //Checking this second, because Shopify errors sometimes return incomplete objects along with errors, // //which cause Json deserialization to throw an exception. Parsing the Shopify error is more important // //than throwing this deserialization exception. // throw response.ErrorException; //} }
public ApiRateLimitException(HttpStatusCode httpStatusCode, Dictionary <string, IEnumerable <string> > errors, string message, string rawBody, RequestSimpleInfo requestInfo = null) : base(httpStatusCode, errors, message, rawBody, requestInfo) { }