private void InsertMetricCallback(CustomMetric content, RequestError error, int index, HttpResponseMessage message) { if (!message.IsSuccessStatusCode) { Logger.Warn(message.StatusCode); } }
/// <summary>A callback method which will be called after an individual response was parsed.</summary> /// <param name="content">The content response or <c>null</c> if the request failed.</param> /// <param name="error">Error or <c>null</c> if the request succeeded.</param> /// <param name="index">The request index.</param> /// <param name="message">The HTTP individual response.</param> public virtual void OnResponse(object content, RequestError error, int index, HttpResponseMessage message) { // Set ETag on the response. var eTagValue = message.Headers.ETag != null ? message.Headers.ETag.Tag : null; var eTagContainer = content as IDirectResponseSchema; if (eTagContainer != null && eTagContainer.ETag == null && eTagValue != null) { eTagContainer.ETag = eTagValue; } }
public bool CanHandleErrorResponse(WebException exception, RequestError error) { if (callOrder != 0 && callOrder != 2) { Assert.Fail("IErrorResponseHandler methods called in wrong order."); } // This handler will only handle the first retry, and will fail every additional request. callOrder++; return !Called; }
private async Task EnsureSuccessAsync(HttpResponseMessage result) { if (!result.IsSuccessStatusCode) { Exception innerException = null; try { // Try to parse the error from the current response. RequestError error = await service.DeserializeError(result).ConfigureAwait(false); // If we were able to get an error object, wrap it in a GoogleApiException // and throw that to use as the inner exception. if (error != null) { // We throw here instead of simply creating a new GoogleApiException // so as to get the StackTrace. throw new GoogleApiException(service.Name, error.ToString()) { Error = error, HttpStatusCode = result.StatusCode }; } } catch (Exception ex) { // If for any reason we couldn't parse the error, // or if we did parse it and threw it wrapped in a GoogleApiException, // let's keep the exception so we can use it as the inner exception // of the final HttpRequestException innerException = ex; } try { // Now that we may have more error detail, let's call EnsureSuccessStatusCode. // We don't want to introduce breaking changes for users that relied on // HttpRequestException before, and importantly on its message format which is the only // way they could access the HttpStatusCode. result.EnsureSuccessStatusCode(); } // If innerException is null that means that our attempt to obtain error information // couldn't parse a RequestError but also didn't throw. So we really don't have any // more information to add. We don't need to do anything. catch (HttpRequestException original) when(innerException != null) { throw new HttpRequestException(original.Message, innerException); } } }
private async Task EnsureSuccessAsync(HttpResponseMessage result) { if (!result.IsSuccessStatusCode) { Exception innerException; try { // Try to parse the error from the current response. RequestError error = await service.DeserializeError(result).ConfigureAwait(false); // If DeserializeError didn't threw, then we got an error object. // We wrap it in a GoogleApiException and throw that to use as the inner exception. // We throw here instead of simply creating a new GoogleApiException // so as to get the StackTrace. throw new GoogleApiException(service.Name) { Error = error, HttpStatusCode = result.StatusCode }; } catch (Exception ex) { // If for any reason we couldn't parse the error, // or if we did parse it and threw it wrapped in a GoogleApiException, // let's keep the exception so we can use it as the inner exception // of the final HttpRequestException innerException = ex; } try { // Now that we may have more error detail, let's call EnsureSuccessStatusCode. // We don't want to introduce breaking changes for users that relied on // HttpRequestException before, and importantly on its message format which is the only // way they could access the HttpStatusCode (pre .NET 5). result.EnsureSuccessStatusCode(); } // innerException is never null, either it's the one thrown by DeserializeError // or is the one thrown by us that wraps the deserialized error object. catch (HttpRequestException original) { throw new HttpRequestException(original.Message, innerException); } } }
/// <summary> /// Creates an API Request Exception. /// </summary> public GoogleApiRequestException(IService service, IRequest request, RequestError error) : base(service, PickMessage(error, null)) { Request = request; RequestError = error; }
public void HandleErrorResponse(WebException exception, RequestError error, WebRequest request) { }
public bool CanHandleErrorResponse(WebException exception, RequestError error) { return false; }
private void CallbackEventErrorMessage(Task content, RequestError error, int index, HttpResponseMessage message, List<ReminderTask> reminderTasks, string errorMessage, Dictionary<int, ReminderTask> errorAppointments, List<ReminderTask> addedTasks) { var phrase = message.ReasonPhrase; var googleEvent = reminderTasks[index]; if (!message.IsSuccessStatusCode) { errorAppointments.Add(index, googleEvent); Logger.ErrorFormat("{0} : {1}{2} - {3}", errorMessage, Environment.NewLine, phrase, googleEvent); } else if (content != null) { addedTasks.Add(CreateReminderTask(content)); } }
public void Download_Error_JsonResponse() { var downloadUri = "http://www.sample.com"; var chunkSize = 100; var error = new RequestError { Code = 12345, Message = "Text", Errors = new[] { new SingleError { Message = "Nested error" } } }; var response = new StandardResponse<object> { Error = error }; var responseText = new NewtonsoftJsonSerializer().Serialize(response); var handler = new MultipleChunksMessageHandler { ErrorResponse = responseText }; handler.StatusCode = HttpStatusCode.BadRequest; handler.ChunkSize = chunkSize; // The media downloader adds the parameter... handler.DownloadUri = new Uri(downloadUri + "?alt=media"); using (var service = CreateMockClientService(handler)) { var downloader = new MediaDownloader(service); downloader.ChunkSize = chunkSize; IList<IDownloadProgress> progressList = new List<IDownloadProgress>(); downloader.ProgressChanged += (p) => { progressList.Add(p); }; var outputStream = new MemoryStream(); downloader.Download(downloadUri, outputStream); var lastProgress = progressList.LastOrDefault(); Assert.That(lastProgress.Status, Is.EqualTo(DownloadStatus.Failed)); GoogleApiException exception = (GoogleApiException) lastProgress.Exception; Assert.That(exception.HttpStatusCode, Is.EqualTo(handler.StatusCode)); // Just a smattering of checks - if these two pass, it's surely okay. Assert.That(exception.Error.Code, Is.EqualTo(error.Code)); Assert.That(exception.Error.Errors[0].Message, Is.EqualTo(error.Errors[0].Message)); } }
public bool CanHandleErrorResponse(WebException exception, RequestError error) { Utilities.ThrowIfNull(exception, "exception"); if (this.State == null) { return false; } HttpWebResponse response = exception.Response as HttpWebResponse; if (response == null) { return false; } return response.StatusCode == HttpStatusCode.Unauthorized; }
/// <summary>Asynchronously executes the batch request.</summary> /// <param name="cancellationToken">Cancellation token to cancel operation.</param> public async Task ExecuteAsync(CancellationToken cancellationToken) { if (Count < 1) { return; } ConfigurableHttpClient httpClient = service.HttpClient; var requests = from r in allRequests select r.ClientRequest; HttpContent outerContent = await CreateOuterRequestContent(requests).ConfigureAwait(false); var result = await httpClient.PostAsync(new Uri(batchUrl), outerContent, cancellationToken) .ConfigureAwait(false); // Will throw as meaningful an exception as possible if there was an error. await EnsureSuccessAsync(result).ConfigureAwait(false); // Get the boundary separator. const string boundaryKey = "boundary="; var fullContent = await result.Content.ReadAsStringAsync().ConfigureAwait(false); var contentType = result.Content.Headers.GetValues("Content-Type").First(); var boundary = contentType.Substring(contentType.IndexOf(boundaryKey) + boundaryKey.Length); int requestIndex = 0; // While there is still content to read, parse the current HTTP response. while (true) { cancellationToken.ThrowIfCancellationRequested(); var startIndex = fullContent.IndexOf("--" + boundary); if (startIndex == -1) { break; } fullContent = fullContent.Substring(startIndex + boundary.Length + 2); var endIndex = fullContent.IndexOf("--" + boundary); if (endIndex == -1) { break; } HttpResponseMessage responseMessage = ParseAsHttpResponse(fullContent.Substring(0, endIndex)); if (responseMessage.IsSuccessStatusCode) { // Parse the current content object. var responseContent = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false); object deserializedContent = null; RequestError error = null; try { deserializedContent = service.Serializer.Deserialize(responseContent, allRequests[requestIndex].ResponseType); } catch (Exception ex) { error = new RequestError { Message = $"The response was read but could not be deserialized using the {nameof(service.Serializer)}.{Environment.NewLine}" + $"The exception thrown on deserializaton was:{Environment.NewLine}" + $"{ex}", }; } allRequests[requestIndex].OnResponse(deserializedContent, error, requestIndex, responseMessage); } else { RequestError error; try { // Parse the error from the current response. error = await service.DeserializeError(responseMessage).ConfigureAwait(false); } catch (GoogleApiException ex) when(ex.Error is object) { error = ex.Error; } allRequests[requestIndex].OnResponse(null, error, requestIndex, responseMessage); } requestIndex++; fullContent = fullContent.Substring(endIndex); } }
/// <summary> /// Creates an API Request Exception. /// </summary> public GoogleApiRequestException(IService service, IRequest request, RequestError error) : base(service, error != null ? error.ToString() : "<null>") { Request = request; RequestError = error; }
public void HandleErrorResponse(WebException exception, RequestError error, WebRequest request) { Assert.AreEqual(1, callOrder++, "IErrorResponseHandler methods called in wrong order."); Assert.IsFalse(Called); Called = true; }
private static string PickMessage(RequestError error, Exception inner) { if (error != null) { return error.ToString(); } if (inner != null) { return inner.Message; } return "An error has ocurred, but no message is available."; }
/// <summary> /// Handles a failed request, and tries to fix it if possible. /// </summary> /// <remarks> /// Can not throw an exception. /// </remarks> /// <returns> /// Returns true if the request was handled and is being retried. /// Returns false if the request could not be retried. /// </returns> private bool HandleFailedRequest(AsyncExecutionState state, WebException exception, out AsyncRequestResult asyncRequestResult) { try { RequestError error = null; // Try to get an error response object. if (exception.Response != null) { IResponse errorResponse = new Response(exception.Response); error = Service.DeserializeError(errorResponse); } // Try to handle the response somehow. if (SupportsRetry && state.Try < MaximumRetries) { // Wait some time before sending another request. Thread.Sleep((int)state.WaitTime); state.WaitTime *= RetryWaitTimeIncreaseFactor; state.Try++; foreach (IErrorResponseHandler handler in GetErrorResponseHandlers()) { if (handler.CanHandleErrorResponse(exception, error)) { // The provided handler was able to handle this error. Retry sending the request. handler.HandleErrorResponse(exception, error, state.CurrentRequest); logger.Warning("Retrying request [{0}]", this); // Begin a new request and when it is completed being assembled, execute it // asynchronously. state.CurrentRequest = CreateWebRequest((request) => { InternalBeginExecuteRequest(state); }); // Signal that this begin/end request pair has no result because it has been retried. asyncRequestResult = null; return(true); } } } // Retrieve additional information about the http response (if applicable). HttpStatusCode status = 0; HttpWebResponse httpResponse = exception.Response as HttpWebResponse; if (httpResponse != null) { status = httpResponse.StatusCode; } // We were unable to handle the exception. Throw it wrapped in a GoogleApiRequestException. asyncRequestResult = new AsyncRequestResult( new GoogleApiRequestException(Service, this, error, exception) { HttpStatusCode = status }); } catch (Exception) { asyncRequestResult = new AsyncRequestResult( new GoogleApiRequestException(Service, this, null, exception)); } return(false); }
private void CallbackEventErrorMessage(Event content, RequestError error, int index, HttpResponseMessage message, List<Appointment> eventList,string errorMessage, Dictionary<int, Appointment> errorAppointments, List<Appointment> modifiedEvents) { var phrase = message.ReasonPhrase; if (!message.IsSuccessStatusCode) { var googleEvent = eventList[index]; errorAppointments.Add(index, googleEvent); Logger.ErrorFormat("{0} : {1}{2} - {3}", errorMessage,Environment.NewLine, phrase, googleEvent); } else { if (content != null) { modifiedEvents.Add(CreateAppointment(content)); } } }
public void HandleErrorResponse(WebException exception, RequestError error, WebRequest request) { Utilities.ThrowIfNull(request, "request"); if (!(request is HttpWebRequest)) { throw new InvalidCastException(string.Concat("Expected a HttpWebRequest, but got a ", request.GetType(), " instead.")); } var tClient = this.tokenProvider; TimeSpan? nullable = null; tClient.RefreshToken(this.State, nullable); this.ApplyAuthenticationToRequest((HttpWebRequest)request); }