示例#1
0
 internal void OnException(object sender, HttpExceptionArgs args) => Exception?.Invoke(sender, args);
示例#2
0
        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);
        }
示例#3
0
 public void OnBeforeExceptionLog(HttpExceptionArgs args)
 {
     BeforeExceptionLog?.Invoke(this, args);
 }