internal void OnException(object sender, HttpExceptionArgs args) => Exception?.Invoke(sender, args);
internal static async Task <HttpCallResponse <T> > SendAsync <T>(IRequestBuilder <T> builder, HttpMethod method, CancellationToken cancellationToken = default) { // default to global settings var settings = builder.GetSettings(); settings.OnBeforeSend(builder, builder.Inner); var request = builder.Inner.Message; request.Method = method; Exception exception = null; HttpResponseMessage response = null; try { using (settings.ProfileRequest?.Invoke(request)) using (request) { // Get the pool var pool = builder.Inner.ClientPool ?? settings.ClientPool; var completionOption = builder.Inner.BufferResponse ? HttpCompletionOption.ResponseContentRead : HttpCompletionOption.ResponseHeadersRead; // Send the request using (response = await pool.Get(builder.Inner).SendAsync(request, completionOption, cancellationToken)) { // If we haven't ignored it, throw and we'll log below // This isn't ideal cntrol flow behavior, but it's the only way to get proper stacks if (!response.IsSuccessStatusCode && !builder.Inner.IgnoredResponseStatuses.Contains(response.StatusCode)) { exception = new HttpClientException($"Response code was {(int)response.StatusCode} ({response.StatusCode}) from {response.RequestMessage.RequestUri}: {response.ReasonPhrase}", response.StatusCode, response.RequestMessage.RequestUri); stackTraceString.SetValue(exception, new StackTrace(true).ToString()); } else { var data = await builder.Handler(response); return(HttpCallResponse.Create(response, data)); } } } } catch (OperationCanceledException ex) { exception = cancellationToken.IsCancellationRequested ? new HttpClientException("HttpClient request cancelled by token request.", builder.Inner.Message.RequestUri, ex) : new HttpClientException("HttpClient request timed out. Timeout: " + builder.Inner.Timeout.TotalMilliseconds.ToString("N0") + "ms", builder.Inner.Message.RequestUri, ex); } catch (Exception ex) { exception = ex; } // Use the response if we have it - request if not var result = response != null ? HttpCallResponse.Create <T>(response, exception) : HttpCallResponse.Create <T>(request, exception); // Add caller member bits to the exception data regardless of where it's eventually logged. (builder.Inner as HttpBuilder)?.AddExceptionData(exception); // If we're told not to log at all, don't log if (builder.Inner.LogErrors) { var args = new HttpExceptionArgs(builder.Inner, exception); builder.Inner.OnBeforeExceptionLog(args); if (!args.AbortLogging) { settings.OnException(builder, args); } } return(result); }
public void OnBeforeExceptionLog(HttpExceptionArgs args) { BeforeExceptionLog?.Invoke(this, args); }